package com.alibaba.citrus.ots.application.report.ability.facade.service;

import com.alibaba.citrus.ots.application.report.ability.utils.DomUtil;
import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.common.exception.FacadeException;
import com.alibaba.citrus.ots.common.util.DateUtils;
import com.alibaba.citrus.ots.common.util.TimeUtil;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.model.dto.BatchQueryCompany2Request;
import com.epoch.app.bcorder.model.dto.CompanySDO;
import com.epoch.app.bcorder.service.BcOrderService;
import com.epoch.app.crb2btradecenter.api.orderlinequery.service.OrderLineQueryService;
import com.epoch.app.crb2btradecenter.enums.OrderStatus;
import com.epoch.app.crb2btradecenter.model.dto.OrderLineStatAmountResponse;
import com.epoch.app.crb2btradecenter.model.dto.PageQueryOrderLineESListRequest;
import com.epoch.app.crforecastsales.api.forecastorderlinequery.service.ForecastOrderLineQueryService;
import com.epoch.app.crforecastsales.enums.ForecastStatusEnum;
import com.epoch.app.crforecastsales.model.dto.GetForecastQuantityListResponse;
import com.epoch.app.crforecastsales.model.dto.GetForecastQuantityResponse;
import com.epoch.app.crforecastsales.model.dto.SearchForecastOrderRequest;
import com.epoch.app.crforecastsales.ofsforecastorderindex.model.OfsForecastOrderIndex;
import com.epoch.app.crforecastsales.ofsforecastorderindex.service.OfsForecastOrderIndexService;
import com.epoch.app.crplatformenhance.enums.OrganizationTypeEnum;
import com.epoch.app.crplatformenhance.model.dto.GetDownOrganizationListRequest;
import com.epoch.app.crplatformenhance.sdo.OrganizationSDO;
import com.epoch.app.crplatformenhance.service.CrPlatformEnhanceService;
import com.epoch.app.otsapplicationreportsdk.forecastorderreportsqueryserviceservice.dto.ForecastOrderReportsMobileQueryRequest;
import com.epoch.app.otsapplicationreportsdk.forecastorderreportsqueryserviceservice.dto.ForecastOrderReportsQueryRequest;
import com.epoch.app.otsapplicationreportsdk.forecastorderreportsqueryserviceservice.dto.QueryChannelInfoRequest;
import com.epoch.app.otsapplicationreportsdk.forecastorderreportsqueryserviceservice.dto.QueryDailyInfoRequest;
import com.epoch.app.otsapplicationreportsdk.forecastorderreportsqueryserviceservice.dto.QueryDepInfoRequest;
import com.epoch.app.otsapplicationreportsdk.forecastorderreportsqueryserviceservice.dto.QueryOrderInfoRequest;
import com.epoch.app.otsapplicationreportsdk.forecastorderreportsqueryserviceservice.dto.QueryTopInfoRequest;
import com.epoch.app.otsapplicationreportsdk.forecastorderreportsqueryserviceservice.service.ForecastOrderReportsQueryServiceServiceService;
import com.epoch.app.otsapplicationreportsdk.model.dto.ChannelDataList;
import com.epoch.app.otsapplicationreportsdk.model.dto.ChannelListResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.CurrentMonth;
import com.epoch.app.otsapplicationreportsdk.model.dto.DailyInfoListResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.DailyInfoResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.DataInfo;
import com.epoch.app.otsapplicationreportsdk.model.dto.DepCountList;
import com.epoch.app.otsapplicationreportsdk.model.dto.DepDateResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.DepInfoListResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.DepInfoResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.ForecastOrderReportsMobileResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.ForecastOrderReportsResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.ForecastOrderReportsTopListResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.ForecastOrderReportsTopNumResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.LastMonth;
import com.epoch.app.otsapplicationreportsdk.model.dto.OrderDetail;
import com.epoch.app.otsapplicationreportsdk.model.dto.Orders;
import com.epoch.app.otsapplicationreportsdk.model.dto.OrdersData;
import com.epoch.app.otsapplicationreportsdk.model.dto.QueryChannelInfoDataResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.QueryChannelInfoListResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.QueryDailyInfoResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.QueryDepInfoListResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.QueryDepInfoResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.QueryOrderInfoResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.QueryTopInfoResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.TabConfigResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.TopInfoDataListResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.TopInfoDataResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.TopInfoDataShellResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.TopList;
import com.epoch.app.otsapplicationreportsdk.model.dto.TopTotalInfoListResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.TopTotalInfoResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.TotalCountList;
import com.google.common.collect.Lists;
import lombok.Data;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Component
public class ForecastOrderReportsQueryServiceImpl implements ForecastOrderReportsQueryServiceServiceService {
    private final Log log = Log.getLogger(ForecastOrderReportsQueryServiceImpl.class);

    @Autowired
    private BcOrderService bcOtsService;
    //    @Autowired
//    private BaseDataService baseDataService;
//    @Autowired
//    private OtsForecastSalesService otsForecastSalesService;
    @Autowired
    private CrPlatformEnhanceService otsPlatformEnhanceService;
    @Autowired
    private ForecastOrderLineQueryService forecastOrderLineQueryService;
    @Autowired
    private OfsForecastOrderIndexService ofsForecastOrderIndexService;
    @Resource
    private OrderLineQueryService orderLineQueryService;
    @Resource(name = "logsCheckSyncTaskExecutor")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    private List<Integer> SUB_ORDER_STATUS = Lists.newArrayList(ForecastStatusEnum.PARTIAL_REPLY.getNumValue(),
            ForecastStatusEnum.COMPLETED.getNumValue());

    private List<Integer> ORDER_STATUS = Lists.newArrayList(ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue(),
            ForecastStatusEnum.PARTIAL_REPLY.getNumValue(),
            ForecastStatusEnum.COMPLETED.getNumValue());

    private List<Integer> WAIT_ORDER_STATUS = Lists.newArrayList(ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue(), ForecastStatusEnum.PARTIAL_REPLY.getNumValue());

    private List<Integer>FINISH_ORDER_STATUS = Lists.newArrayList(ForecastStatusEnum.PARTIAL_REPLY.getNumValue(),
            ForecastStatusEnum.COMPLETED.getNumValue());

    private List<Integer> REFUSE_ORDER_STATUS = Lists.newArrayList(ForecastStatusEnum.COMPLETED.getNumValue());

    private List<Long> ALL_STATUS = Lists.newArrayList(2L, 3L, 4L);

    private List<Long> FINISH_STATUS = Lists.newArrayList(3L, 4L);

    private List<String> COLOR_LIST = Lists.newArrayList("#FF6A00", "#1A7DFF", "#28C8D7", "#7561FD", "#7C99AA");

    private List<String> TAB_CONFIG = Lists.newArrayList("渠道名称", "提报数量", "待回复数量","已回复数量", "已拒绝数量", "订单满足率");

    private List<String> TAB_DATA_KEY = Lists.newArrayList("channelName", "quantity", "waitNum", "finishNum", "refuseNum","orderFillRate");

    private OrderLineStatAmountResponse statSaleOrderLine(String saleOrgId,Date beginDate, Date endDate){
        PageQueryOrderLineESListRequest queryRequest = init(saleOrgId, beginDate, endDate);
        Result<OrderLineStatAmountResponse> result = orderLineQueryService.statAmountES(queryRequest);
        if (result == null){
            return null;
        }
        return result.getResult();
    }
    private PageQueryOrderLineESListRequest init(String saleOrgId,Date beginDate, Date endDate){
        PageQueryOrderLineESListRequest request = new PageQueryOrderLineESListRequest();
        if (org.apache.commons.lang3.StringUtils.isNotBlank(saleOrgId)){
            request.setOrganizationCodes(Lists.newArrayList(saleOrgId));
        }
        if (beginDate != null){
            request.setGmtCreateStartTime(beginDate);
        }
        if (endDate != null){
            request.setGmtCreateEndTime(endDate);
        }
        request.setSubOrderStatusList(Stream.of(OrderStatus.values()).filter(orderStatus -> !OrderStatus.CANCELLED.equals(orderStatus))
                .map(OrderStatus::getCode).map(String::valueOf).collect(Collectors.toList()));
        return request;
    }
    @Override
    @FacadeInvoker
    public Result<ForecastOrderReportsMobileResponse> forecastOrderReportsMobileQuery(ForecastOrderReportsMobileQueryRequest forecastOrderReportsMobileQueryRequest){
        String companyCode = getCompanyCode(forecastOrderReportsMobileQueryRequest.getCompanyCode());
        String salesOrgId = getSalesOrgByCompanyOrgId(companyCode);
        //处理数据表数据
//        //获取日期
//        Date date = forecastOrderReportsMobileQueryRequest.getStatisticalDate()!=null?DateUtils.parse(forecastOrderReportsMobileQueryRequest.getStatisticalDate()):null;
//        List<Date> dates = getTodayFormatDate(date);
//        //获取昨天日期
//        List<Date> yesterdays = getYesterdaysDateFormat(date);
//        checkDate(forecastOrderReportsMobileQueryRequest.getBeginDate(),forecastOrderReportsMobileQueryRequest.getEndDate());
        //获取时间段日期
        List<Date> dates = getThisFormatDate(forecastOrderReportsMobileQueryRequest.getBeginDate(),forecastOrderReportsMobileQueryRequest.getEndDate());
        //获取前段日期
        List<Date> previousDates = getLastFormatDate(forecastOrderReportsMobileQueryRequest.getBeginDate(),forecastOrderReportsMobileQueryRequest.getEndDate());

        //获取当天所有主单
        List<OfsForecastOrderIndex> orderToday = queryMainOrderList(salesOrgId, dates.get(0), dates.get(1));
        //获取昨天所有主单
        List<OfsForecastOrderIndex> orderYesterday = queryMainOrderList(salesOrgId, previousDates.get(0), previousDates.get(1));

        //今天子单提报数量list
        List<GetForecastQuantityResponse> subToday = querySubOrderList(salesOrgId, dates.get(0), dates.get(1));
        //昨日子单提报数量list
        List<GetForecastQuantityResponse> subYesterdays = querySubOrderList(salesOrgId, previousDates.get(0), previousDates.get(1));
        //2022.12.19 修改逻辑 已回复金额 从销售子单中获取
         //根据页面选择时间段 ->往前推的时间段获取的子单
        OrderLineStatAmountResponse statAmountResponse = null;
        OrderLineStatAmountResponse previousStatResponse = null;
        Pair<OrderLineStatAmountResponse, OrderLineStatAmountResponse> pair = getStatResponse(salesOrgId, dates, previousDates);
        if (pair != null){
            statAmountResponse = pair.getKey();
            previousStatResponse = pair.getValue();
        }
        QueryOrderInfoResponse orderInfoResponse = buildOrderInfo(orderToday, orderYesterday, subToday, subYesterdays,statAmountResponse,previousStatResponse);

        //获取拒绝原因数据
        QueryTopInfoResponse topInfoResponse = buildTopInfo(subToday);

        //获取渠道数据
        QueryChannelInfoListResponse channelDataListResponse = buildChannelInfo(subToday);

        //获取部门维度数据
        QueryDepInfoListResponse queryDepInfoResponse = buildDepInfo(subToday);

        ForecastOrderReportsMobileResponse response = buildForecastResponse(orderInfoResponse,topInfoResponse,channelDataListResponse,queryDepInfoResponse);
        List<DailyInfoListResponse> dailyInfoListResponses = buildMobileDailyInfo(salesOrgId);
        response.setDailyInfoList(dailyInfoListResponses);
        return Result.success(response);
    }

    private ForecastOrderReportsMobileResponse buildForecastResponse(QueryOrderInfoResponse orderInfoResponse,
                                                                     QueryTopInfoResponse topInfoResponse,
                                                                     QueryChannelInfoListResponse channelDataListResponse,
                                                                     QueryDepInfoListResponse queryDepInfoResponse){
        ForecastOrderReportsMobileResponse response = new ForecastOrderReportsMobileResponse();
        if(Objects.nonNull(orderInfoResponse)){
            Orders orders = new Orders();
            List<OrdersData> data = Lists.newArrayList();

            //提报单
            OrdersData quantity = new OrdersData();
            //提报数量
            quantity.setValue(orderInfoResponse.getOrders());
            quantity.setTitle("提报单数(单)");
            String ordersCompare = orderInfoResponse.getOrdersCompare();
            quantity.setPercent(ordersCompare);
            quantity.setUnit("0.00%".equals(ordersCompare)?0:ordersCompare.contains("-")?-1:1);
            //已回复单
            OrdersData alreadyQuantity = new OrdersData();
            alreadyQuantity.setTitle("已回复单数(单)");
            alreadyQuantity.setValue(orderInfoResponse.getReOrders());
            String reOrdersCompare = orderInfoResponse.getReOrdersCompare();
            alreadyQuantity.setPercent(reOrdersCompare);
            alreadyQuantity.setUnit("0.00%".equals(reOrdersCompare)?0:reOrdersCompare.contains("-")?-1:1);

            data.add(quantity);
            data.add(alreadyQuantity);
            orders.setData(data);
            orders.setRate(orderInfoResponse.getOrderFillRate());
            //主单数量相关信息
            response.setOrders(orders);

            //子单提报件数
            OrderDetail detail = new OrderDetail();
            List<OrdersData> detailData = Lists.newArrayList();

            //提报件数
            OrdersData quantityNumObject = new OrdersData();
            quantityNumObject.setValue(orderInfoResponse.getQuantityNum());
            quantityNumObject.setTitle("提报数量(件)");
            quantityNumObject.setMoney(orderInfoResponse.getOrderMoney());
            quantityNumObject.setSubTitle("提报金额(元)");
            String quantityNumCompare = orderInfoResponse.getQuantityNumCompare();
            quantityNumObject.setPercent(quantityNumCompare);
            quantityNumObject.setUnit("0.00%".equals(quantityNumCompare)?0:quantityNumCompare.contains("-")?-1:1);

            //待回复数量
            OrdersData wait = new OrdersData();
            wait.setValue(orderInfoResponse.getWaitNum());
            wait.setTitle("待回复数量(件)");
            wait.setMoney(orderInfoResponse.getWaitNumMoney());
            wait.setSubTitle("待回复金额(元)");
            String waitCompare = orderInfoResponse.getWaitNumCompare();
            wait.setPercent(waitCompare);
            wait.setUnit("0.00%".equals(waitCompare)?0:waitCompare.contains("-")?-1:1);

            //已回复数量
            OrdersData finish = new OrdersData();
            finish.setValue(orderInfoResponse.getFinishNum());
            finish.setTitle("已回复数量(件)");
            finish.setMoney(orderInfoResponse.getFinishNumMoney());
            finish.setSubTitle("已回复金额(元)");
            String finishCompare = orderInfoResponse.getFinishNumCompare();
            finish.setPercent(finishCompare);
            finish.setUnit("0.00%".equals(finishCompare)?0:finishCompare.contains("-")?-1:1);

            detailData.add(quantityNumObject);
            detailData.add(wait);
            detailData.add(finish);
            detail.setData(detailData);
            detail.setRate(orderInfoResponse.getQuantityFillRate());

            response.setOrderDetail(detail);
        }

        //处理拒绝原因
        if(Objects.nonNull(topInfoResponse) && CollectionUtils.isNotEmpty(topInfoResponse.getTopTotalInfoListResponse().getList())){
            TopList topList = new TopList();

            //拒绝原因总数
            List<TotalCountList> totalCountList = Lists.newArrayList();
            TopTotalInfoListResponse topTotalInfoListResponse = topInfoResponse.getTopTotalInfoListResponse();
            List<TopTotalInfoResponse> topTotalInfoResponses = topTotalInfoListResponse.getList();
            for (TopTotalInfoResponse list : topTotalInfoResponses) {
                TotalCountList totalCount = new TotalCountList();
                totalCount.setTitle(list.getLabel());
                totalCount.setValue(list.getValue());
                totalCountList.add(totalCount);
            }
            topList.setTotalCountList(totalCountList);

            //拒绝原因部门维度
            List<DepCountList> depCountList = Lists.newArrayList();
            TopInfoDataListResponse topInfoDataListResponse = topInfoResponse.getTopInfoDataListResponse();
            List<TopInfoDataShellResponse> topInfoDataShellResponses = topInfoDataListResponse.getList();
            //2022.12.26 这里先根据每个部门下的
            if (CollectionUtils.isNotEmpty(topInfoDataShellResponses)){
                List<TopInfoDataResponse> topInfoDataResponses = topInfoDataShellResponses.stream().map(TopInfoDataShellResponse::getData).filter(CollectionUtils::isNotEmpty)
                        .flatMap(Collection::stream).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(topInfoDataResponses)){
                    Map<String, List<TopInfoDataResponse>> map = topInfoDataResponses.stream().collect(Collectors.groupingBy(TopInfoDataResponse::getDepCode));
                    LinkedHashSet<Map.Entry<String, List<TopInfoDataResponse>>> set = map.entrySet().stream().sorted(Comparator.comparing(stringListEntry -> {
                        int sum = stringListEntry.getValue().stream()
                                .map(TopInfoDataResponse::getValue)
                                .filter(Objects::nonNull)
                                .mapToInt(Integer::intValue).sum();
                        return -sum;
                    })).collect(Collectors.toCollection(LinkedHashSet::new));
                    set.forEach(stringListEntry -> {
                        List<TopInfoDataResponse> values = stringListEntry.getValue();
                        Collections.sort(values,Comparator.comparing(TopInfoDataResponse::getValue).reversed());
                        for (TopInfoDataResponse topInfoDataRespons : values) {
                            DepCountList depCount = new DepCountList();
                            //原因
                            depCount.setColor(topInfoDataRespons.getColor());
                            //部门名称
                            depCount.setName(topInfoDataRespons.getName());
                            //金额
                            depCount.setMoney(topInfoDataRespons.getMoney());
                            //数量
                            depCount.setValue(topInfoDataRespons.getValue());
                            depCountList.add(depCount);
                        }
                    });
                }
            }
            topList.setDepCountList(depCountList);
            response.setTopList(topList);
        }

        //处理渠道数据
        if(Objects.nonNull(channelDataListResponse) && CollectionUtils.isNotEmpty(channelDataListResponse.getList())){
            ChannelDataList channelDataList = new ChannelDataList();
            List<TabConfigResponse> tabConfig = Lists.newArrayList();
            for(int i = 0;i<6;i++){
                TabConfigResponse tab = new TabConfigResponse();
                tab.setTitle(TAB_CONFIG.get(i));
                tab.setDataKey(TAB_DATA_KEY.get(i));
                tab.setWidth("80");
                tabConfig.add(tab);
            }
            channelDataList.setTabConfig(tabConfig);

            //处理数据
            List<QueryChannelInfoDataResponse> channelDataSource = Lists.newArrayList();
            List<QueryChannelInfoDataResponse> queryChannelInfoDataResponses = channelDataListResponse.getList();
            for (QueryChannelInfoDataResponse queryChannelInfoDataRespons : queryChannelInfoDataResponses) {
                QueryChannelInfoDataResponse dataSource = new QueryChannelInfoDataResponse();
                BeanUtils.copyProperties(queryChannelInfoDataRespons,dataSource);
                channelDataSource.add(dataSource);
            }
            channelDataList.setChannelDataSource(channelDataSource);
            response.setChannelDataList(channelDataList);
        }

        //渠道部门维度分析
        if(Objects.nonNull(queryDepInfoResponse) && CollectionUtils.isNotEmpty(queryDepInfoResponse.getList())){
            List<QueryDepInfoResponse> queryDepInfoResponses = queryDepInfoResponse.getList();
            List<ChannelListResponse> channelList = Lists.newArrayList();
            for (QueryDepInfoResponse queryDepInfoRespons : queryDepInfoResponses) {
                ChannelListResponse channelListResponse = new ChannelListResponse();
                //渠道名称
                channelListResponse.setChannelName(queryDepInfoRespons.getTitle());

                //下方图示详情
                List<DepInfoListResponse> depList = Lists.newArrayList();
                List<DepInfoResponse> depInfoResponses = queryDepInfoRespons.getData();
                for (DepInfoResponse depInfoRespons : depInfoResponses) {
                    DepInfoListResponse dep = new DepInfoListResponse();
                    dep.setTitle(depInfoRespons.getColor());
                    dep.setNum(depInfoRespons.getValue());
                    dep.setDepName(depInfoRespons.getName());
                    dep.setPercent(depInfoRespons.getPercent());
                    dep.setValue(depInfoRespons.getValueFormit());
                    depList.add(dep);
                }
                channelListResponse.setDepInfoList(depList);

                //汇总渠道数据
                List<DepDateResponse> depDateList = Lists.newArrayList();
                List<QueryChannelInfoDataResponse> channelDataSource = response.getChannelDataList().getChannelDataSource();
                List<QueryChannelInfoDataResponse> channelDataSourceFilter = channelDataSource.stream().filter(x->x.getChannelName().equals(queryDepInfoRespons.getTitle())).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(channelDataSourceFilter)){
                    QueryChannelInfoDataResponse channelInfoData = channelDataSourceFilter.get(0);
                    DepDateResponse quantity = new DepDateResponse();
                    quantity.setTitle("提报数量(件)");
                    quantity.setValue(channelInfoData.getQuantity());
                    depDateList.add(quantity);

                    DepDateResponse waitNum = new DepDateResponse();
                    waitNum.setTitle("待回复数量(件)");
                    waitNum.setValue(channelInfoData.getWaitNum());
                    depDateList.add(waitNum);

                    DepDateResponse finishNum = new DepDateResponse();
                    finishNum.setTitle("已回复数量(件)");
                    finishNum.setValue(channelInfoData.getFinishNum());
                    depDateList.add(finishNum);

                    DepDateResponse refuseNum = new DepDateResponse();
                    refuseNum.setTitle("已拒绝数量(件)");
                    refuseNum.setValue(channelInfoData.getRefuseNum());
                    depDateList.add(refuseNum);

                    channelListResponse.setDepDate(depDateList);
                }
                channelList.add(channelListResponse);
            }
            response.setChannelList(channelList);
        }
        return response;
    }

    /**
     * 小程序端每日分析数据封装
     * @param salesOrgId
     * @return
     */
    private List<DailyInfoListResponse> buildMobileDailyInfo(String salesOrgId) {
        Date date = new Date();
        //获取本月及上月日期
        List<Integer> dateList = getYearAndMonth(date);
        Integer year = dateList.get(0);
        //当前月
        Integer currentMonth = dateList.get(1);
        //上个月
        Integer lastMonth = dateList.get(2);

        //获取当月所有日期
        List<String> currentMonthDate = getMonthFullDay(year, currentMonth);
        //当月开始日期
        String currentMonthBeginDate = currentMonthDate.get(0) + " 00:00:00";
        //当月结束日期
        String currentMonthEndDate = currentMonthDate.get(currentMonthDate.size() - 1) + " 23:59:59";
        //获取上月所有日期
        List<String> lastMonthDate = getMonthFullDay(year, lastMonth);
        //上月开始日期
        String lastMonthBeginDate = lastMonthDate.get(0) + " 00:00:00";
        //上月结束日期
        String lastMonthEndDate = lastMonthDate.get(lastMonthDate.size() - 1) + " 23:59:59";

        //获取当月所有子单
        List<GetForecastQuantityResponse> subCurrentMonth =
                querySubOrderList(salesOrgId, getDateFormat(currentMonthBeginDate), getDateFormat(currentMonthEndDate));
        log.info("buildDailyInfo.subCurrentMonth {}",JSONObject.toJSONString(subCurrentMonth));

        //获取上月所有子单
        List<GetForecastQuantityResponse> subLastMonth =
                querySubOrderList(salesOrgId, getDateFormat(lastMonthBeginDate), getDateFormat(lastMonthEndDate));
        log.info("buildDailyInfo.subLastMonth {}",JSONObject.toJSONString(subLastMonth));

        List<DailyInfoListResponse> dailyInfoList = Lists.newArrayList();
        //计算当月
        if (CollectionUtils.isNotEmpty(subCurrentMonth)) {
            currentMonthDate.forEach(e -> {
                DailyInfoListResponse currentDay = new DailyInfoListResponse();
                Date beginDate = getDateFormat(e + " 00:00:00");
                Date endDate = getDateFormat(e + " 23:59:59");
                //获取此日期内的所有符合要求的数据,并计算提报数量
                BigDecimal quantity = subCurrentMonth.stream().
                        filter(o -> ORDER_STATUS.contains(o.getMainStatus()) &&
                                Objects.nonNull(o.getVaildBeginTime()) &&
                                o.getVaildBeginTime().after(beginDate) &&
                                o.getVaildBeginTime().before(endDate)).
                        map(x->calculateQuantity(x.getQuantity(),x.getUnitConvert()))
                        .reduce(BigDecimal.ZERO,BigDecimal::add)
                        .setScale(0,BigDecimal.ROUND_HALF_UP);
                //当月当日提报量
                currentDay.setNum(quantity);
                String[] dayArray = e.split("-");
                currentDay.setDay(dayArray[2]);
                currentDay.setName("currentMonth");
//                DataInfo quantityDataInfo = getQuantityFormat(quantity);
//                if(quantity > 100000){
//                    current.setValue(quantityDataInfo.getValue() + "万件");
//                }else{
//                    current.setValue(quantityDataInfo.getValue() + "件");
//                }
                currentDay.setValue(fmtMicrometer(quantity + ""));
                dailyInfoList.add(currentDay);
            });
        }else{
            currentMonthDate.forEach(e->{
                DailyInfoListResponse currentDay = new DailyInfoListResponse();
                currentDay.setNum(new BigDecimal(0));
                String[] dayArray = e.split("-");
                currentDay.setDay(dayArray[2]);
                currentDay.setName("currentMonth");
                currentDay.setValue(fmtMicrometer("0") + "件");
                dailyInfoList.add(currentDay);
            });
        }
        log.info("buildDailyInfo.currentMonthList {}",JSONObject.toJSONString(dailyInfoList));

        //上月统计值
        if (CollectionUtils.isNotEmpty(subLastMonth)) {
            lastMonthDate.forEach(e -> {
                DailyInfoListResponse lastDay = new DailyInfoListResponse();
                Date beginDate = getDateFormat(e + " 00:00:00");
                Date endDate = getDateFormat(e + " 23:59:59");
                //获取此日期内的所有符合要求的数据,并计算提报数量
                BigDecimal quantity = subLastMonth.stream().
                        filter(o -> ORDER_STATUS.contains(o.getMainStatus()) &&
                                Objects.nonNull(o.getVaildBeginTime()) &&
                                o.getVaildBeginTime().after(beginDate) &&
                                o.getVaildBeginTime().before(endDate)).
                        map(x->calculateQuantity(x.getQuantity(),x.getUnitConvert()))
                        .reduce(BigDecimal.ZERO,BigDecimal::add)
                        .setScale(0,BigDecimal.ROUND_HALF_UP);
                //当月当日提报量
                lastDay.setNum(quantity);
                String[] dayArray = e.split("-");
                lastDay.setDay(dayArray[2]);
                lastDay.setName("lastMonth");
//                DataInfo quantityDataInfo = getQuantityFormat(quantity);
//                if(quantity > 100000){
//                    last.setValue(quantityDataInfo.getValue() + "万件");
//                }else{
//                    last.setValue(quantityDataInfo.getValue() + "件");
//                }
                lastDay.setValue(fmtMicrometer(quantity + ""));
                dailyInfoList.add(lastDay);
            });
        }else{
            lastMonthDate.forEach(e->{
                DailyInfoListResponse lastDay = new DailyInfoListResponse();
                lastDay.setNum(new BigDecimal(0));
                String[] dayArray = e.split("-");
                lastDay.setDay(dayArray[2]);
                lastDay.setName("lastMonth");
                lastDay.setValue(fmtMicrometer("0") + "件");
                dailyInfoList.add(lastDay);
            });
        }
        log.info("buildDailyInfo.monthLastList {}",JSONObject.toJSONString(dailyInfoList));
        return dailyInfoList;
    }


    @Override
    @FacadeInvoker
    public Result<QueryOrderInfoResponse> queryOrderInfo(QueryOrderInfoRequest queryOrderInfoRequest) {
        String companyCode = getCompanyCode(queryOrderInfoRequest.getCompanyCode());
        String salesOrgId = getSalesOrgByCompanyOrgId(companyCode);
//        checkDate(queryOrderInfoRequest.getBeginDate(),queryOrderInfoRequest.getEndDate());
        //获取时间段日期
        List<Date> dates = getThisFormatDate(queryOrderInfoRequest.getBeginDate(),queryOrderInfoRequest.getEndDate());
        //获取前段日期
        List<Date> previousDates = getLastFormatDate(queryOrderInfoRequest.getBeginDate(),queryOrderInfoRequest.getEndDate());
        //获取时间段所有主单
        List<OfsForecastOrderIndex> orderToday = queryMainOrderList(salesOrgId, dates.get(0), dates.get(1));
        log.info("view_queryOrderInfo_orderToday_size={}",orderToday.size());
        //获取前段所有主单
        List<OfsForecastOrderIndex> orderYesterday = queryMainOrderList(salesOrgId, previousDates.get(0), previousDates.get(1));
        log.info("view_queryOrderInfo_orderYesterday_size={}",orderYesterday.size());
        //今天子单提报数量list
        List<GetForecastQuantityResponse> subToday = querySubOrderList(salesOrgId, dates.get(0), dates.get(1));
        log.info("view_queryOrderInfo_subToday_size={}",subToday.size());
        //昨日子单提报数量list
        List<GetForecastQuantityResponse> subYesterdays = querySubOrderList(salesOrgId, previousDates.get(0), previousDates.get(1));
        log.info("view_queryOrderInfo_subYesterdays_size={}",subYesterdays.size());

        //2022.12.19 修改逻辑 已回复金额 从销售子单中获取
        //页面选择时间段获取的子单
        OrderLineStatAmountResponse statAmountResponse = null;
        OrderLineStatAmountResponse previousStatResponse = null;
        Pair<OrderLineStatAmountResponse, OrderLineStatAmountResponse> pair = getStatResponse(salesOrgId, dates, previousDates);
        if (pair != null){
            statAmountResponse = pair.getKey();
            previousStatResponse = pair.getValue();
        }

        //根据页面选择时间段 ->往前推的时间段获取的子单
        QueryOrderInfoResponse result = buildOrderInfo(orderToday, orderYesterday, subToday, subYesterdays,statAmountResponse,previousStatResponse);
        return Result.success(result);
    }

    private QueryOrderInfoResponse buildOrderInfo(List<OfsForecastOrderIndex> orderToday,
                                                  List<OfsForecastOrderIndex> orderYesterday,
                                                  List<GetForecastQuantityResponse> subToday,
                                                  List<GetForecastQuantityResponse> subYesterdays,
                                                  OrderLineStatAmountResponse orderLineStatAmountResponse,
                                                  OrderLineStatAmountResponse previousStatAmountResponse) {
        Integer todayOrders = 0;
        Integer yesterdayOrders = 0;
        QueryOrderInfoResponse response = new QueryOrderInfoResponse();
        if (CollectionUtils.isNotEmpty(orderToday)) {
            todayOrders = orderToday.stream().filter(
                    o -> ALL_STATUS.contains(o.getMainStatus())
            ).collect(Collectors.toList()).size();
        }
        if (CollectionUtils.isNotEmpty(orderYesterday)) {
            yesterdayOrders = orderYesterday.stream().filter(
                    o -> ALL_STATUS.contains(o.getMainStatus())
            ).collect(Collectors.toList()).size();
        }
        //提报单数
        DataInfo ordersSize = getQuantityFormatForForecastOrder(todayOrders);
        response.setOrders(ordersSize.getValue());
        CompareInfo orderCompare = getCompareValue(todayOrders, yesterdayOrders);
        //提报数量较昨日比值
        response.setOrdersCompare(orderCompare.getValue());

        Integer reOrders = 0;
        Integer yesterdayReOrders = 0;
        if (CollectionUtils.isNotEmpty(orderToday)) {
            reOrders = orderToday.stream().filter(
                    o -> FINISH_STATUS.contains(o.getMainStatus())
            ).collect(Collectors.toList()).size();
        }
        if (CollectionUtils.isNotEmpty(orderYesterday)) {
            yesterdayReOrders = orderYesterday.stream().filter(
                    o -> FINISH_STATUS.contains(o.getMainStatus())
            ).collect(Collectors.toList()).size();
        }

        DataInfo reOrdersDataInfo = getQuantityFormatForForecastOrder(reOrders);
        response.setOrders(ordersSize.getValue());
        CompareInfo reOrderCompare = getCompareValue(reOrders, yesterdayReOrders);
        //已回复单数
        response.setReOrders(reOrdersDataInfo.getValue());
        //已回复单数较昨日比值
        response.setReOrdersCompare(reOrderCompare.getValue());
        //订单满足率，已回复/提报数量
        //已回复单量/提报量 = 占比
        String[] orderFillRateArray =  getProportionOfReplies(todayOrders, reOrders);
//        String orderFillRate = getFillRate(reOrders, todayOrders);
        response.setOrderFillRate(orderFillRateArray[0]+"."+orderFillRateArray[1]+ "%");

        //处理子单提报数量---------------------------------------------------------
        //今天子单所有提报件数
        Integer quantityNumToday = 0;
        BigDecimal moneyToday = new BigDecimal(0);
        if (CollectionUtils.isNotEmpty(subToday)) {
            //quantityNumToday = getQuantity(subToday).getNum();
            Map<String,NumInfo> result = getQuantityAndMoney(subToday);
            quantityNumToday = result.get("quantity").getNum();
            moneyToday = result.get("money").getMoney();
        }
        if(quantityNumToday >= 100000){
            DataInfo quantityNumDataInfo = getQuantityFormat(quantityNumToday);
            response.setQuantityNum(quantityNumDataInfo.getValue() + "万");
        }else{
            response.setQuantityNum(fmtMicrometer(quantityNumToday + ""));
        }
        //提报金额
        if(moneyToday.compareTo(new BigDecimal(100000))>=0){
            DataInfo moneyDataInfo = getMoneyFormat(moneyToday);
            response.setOrderMoney(moneyDataInfo.getValue()+moneyDataInfo.getTail() + "万");
        }else{
            response.setOrderMoney(fmtMicrometer(moneyToday.toString()));
        }

        //昨天子单所有提报件数
        Integer quantityNumYesterday = 0;
        if (CollectionUtils.isNotEmpty(subYesterdays)) {
            quantityNumYesterday = getQuantity(subYesterdays).getNum();
        }
        CompareInfo quantityNumCompare = getCompareValue(quantityNumToday, quantityNumYesterday);
        //提报数量较昨日比值
        response.setQuantityNumCompare(quantityNumCompare.getValue());

        //待回复数量，状态是2和3，每一行的预报数量-累计数量
        Integer waitNum = 0;
        BigDecimal waitNumMoney = new BigDecimal(0);
        if (CollectionUtils.isNotEmpty(subToday)) {
            //waitNum = getWaitNum(subToday).getNum();
            Map<String,NumInfo> result = getWaitNumAndMoney(subToday);
            waitNum = result.get("quantity").getNum();
            waitNumMoney = result.get("money").getMoney();
        }
        if(waitNum >= 100000){
            DataInfo waitNumDataInfo = getQuantityFormat(waitNum);
            response.setWaitNum(waitNumDataInfo.getValue() + "万");
        }else{
            response.setWaitNum(fmtMicrometer(waitNum + ""));
        }
        //待回复金额
        if(waitNumMoney.compareTo(new BigDecimal(100000))>=0){
            DataInfo moneyDataInfo = getMoneyFormat(waitNumMoney);
            response.setWaitNumMoney(moneyDataInfo.getValue()+moneyDataInfo.getTail() + "万");
        }else{
            response.setWaitNumMoney(fmtMicrometer(waitNumMoney.toString()));
        }

        Integer waitNumYesterday = 0;
        if (CollectionUtils.isNotEmpty(subYesterdays)) {
            waitNumYesterday = getWaitNum(subYesterdays).getNum();
        }
        CompareInfo waitNumCompare = getCompareValue(waitNum, waitNumYesterday);
        //待回复数量较昨日比值
        response.setWaitNumCompare(waitNumCompare.getValue());

        //已回复数量，状态是3，4，每一行的累计数量
        Integer finishNum = 0;
        BigDecimal finishNumMoney = new BigDecimal(0);
        if (orderLineStatAmountResponse != null){
            //交货单数量
            BigDecimal totalDeliveryQuantityAndBaseUnit = orderLineStatAmountResponse.getTotalDeliveryQuantityAndBaseUnit();
            if (totalDeliveryQuantityAndBaseUnit != null){
                finishNum = totalDeliveryQuantityAndBaseUnit.setScale(0, RoundingMode.HALF_UP).intValue();
            }
        }
//        if (CollectionUtils.isNotEmpty(subToday)) {
//            //finishNum = getFinishNum(subToday).getNum();
//            Map<String,NumInfo> result = getFinishNumAndMoney(subToday);
//            finishNum = result.get("quantity").getNum();
////            finishNumMoney = result.get("money").getMoney();
//        }
        if(finishNum >= 100000){
            DataInfo finishNumDataInfo = getQuantityFormat(finishNum);
            response.setFinishNum(finishNumDataInfo.getValue() + "万");
        }else{
            response.setFinishNum(fmtMicrometer(finishNum + ""));
        }
        //已回复金额
        if (orderLineStatAmountResponse != null){
            BigDecimal totalAfterDiscountAmountOfDeliveryNote = orderLineStatAmountResponse.getTotalAfterDiscountAmountOfDeliveryNote();
            if (totalAfterDiscountAmountOfDeliveryNote != null){
                finishNumMoney = totalAfterDiscountAmountOfDeliveryNote;
            }
//            long sum = orderLineSelectedDays.stream().map(OrderLinePageQueryResponse::getAfterDiscountAmountOfDeliveryNote)
//                    .filter(Objects::nonNull)
//                    .reduce(0L, (a, b) -> a + b)
//                    .longValue();
//            finishNumMoney = new BigDecimal(sum).movePointLeft(2);
        }
        if(finishNumMoney.compareTo(new BigDecimal(100000))>=0){
            DataInfo moneyDataInfo = getMoneyFormat(finishNumMoney);
            response.setFinishNumMoney(moneyDataInfo.getValue()+moneyDataInfo.getTail() + "万");
        }else{
            response.setFinishNumMoney(fmtMicrometer(finishNumMoney.toString()));
        }

        Integer finishNumPreviousDays = 0;
        //这里的前阶段数量为交货单数量 2022.12.26
        if (previousStatAmountResponse != null && previousStatAmountResponse.getTotalDeliveryQuantityAndBaseUnit()!=null){
            finishNumPreviousDays = previousStatAmountResponse.getTotalDeliveryQuantityAndBaseUnit()
                    .setScale(0,RoundingMode.HALF_UP).intValue();
        }
        CompareInfo waitYesterdayNumCompare = getCompareValue(finishNum, finishNumPreviousDays);
        response.setFinishNumCompare(waitYesterdayNumCompare.getValue());

        //订单满足率，已回复/提报数量
//        String quantityFillRate = getFillRate(reOrders, todayOrders);
        String[] quantityFillRateArray =  getProportionOfReplies(quantityNumToday, finishNum);
        response.setQuantityFillRate(quantityFillRateArray[0] + "." + quantityFillRateArray[1] + "%");
        return response;
    }

    /**
     * 拒绝原因分析
     * @param queryTopInfoRequest
     * @return
     */
    @Override
    public Result<QueryTopInfoResponse> queryTopInfo(QueryTopInfoRequest queryTopInfoRequest) {
        String companyCode = getCompanyCode(queryTopInfoRequest.getCompanyCode());
        String salesOrgId = getSalesOrgByCompanyOrgId(companyCode);
        //获取日期
        List<Date> dates = getThisFormatDate(queryTopInfoRequest.getBeginDate(),queryTopInfoRequest.getEndDate());
        //获取当天所有子单
        List<GetForecastQuantityResponse> subToday = querySubOrderList(salesOrgId, dates.get(0), dates.get(1));
        QueryTopInfoResponse result = buildTopInfo(subToday);
        return Result.success(result);
    }

    private QueryTopInfoResponse buildTopInfo(List<GetForecastQuantityResponse> subToday) {
        //通过状态过滤拒绝原因非空的数据
        if (CollectionUtils.isEmpty(subToday)) {
            return null;
        }
        List<GetForecastQuantityResponse> reasonIsNotNullList = subToday.stream().filter(e ->
                SUB_ORDER_STATUS.contains(e.getMainStatus()) &&
                        ForecastStatusEnum.COMPLETED.getNumValue().equals(e.getDetailStatus()) &&
                        StringUtils.isNotBlank(e.getRefuseReasonCode())
        ).collect(Collectors.toList());

        if(CollectionUtils.isEmpty(reasonIsNotNullList)){
            return null;
        }

        Map<String, List<GetForecastQuantityResponse>> map =
                reasonIsNotNullList.stream().collect(Collectors.groupingBy(GetForecastQuantityResponse::getRefuseReasonCode));
        List<TopGroupCount> count = Lists.newArrayList();
        for (Map.Entry<String, List<GetForecastQuantityResponse>> entry : map.entrySet()) {
            String reasonCode = entry.getKey();
            List<GetForecastQuantityResponse> groupList = entry.getValue();
            TopGroupCount topGroupCount = new TopGroupCount();
            topGroupCount.setCode(reasonCode);
            BigDecimal total = groupList.stream().map(x->
                        calculateQuantity(x.getQuantity(),x.getUnitConvert()).subtract(calculateQuantity(x.getActualTotalReplyAmount(),x.getUnitConvert())))
                    .reduce(BigDecimal.ZERO,BigDecimal::add)
                    .setScale(0,BigDecimal.ROUND_HALF_UP);
            topGroupCount.setTotal(total.intValue());
            topGroupCount.setName(groupList.get(0).getRefuseReason());
            count.add(topGroupCount);
        }
        //获取最终的前五
        List<TopGroupCount> topLimit =
                count.stream().sorted(Comparator.comparing(TopGroupCount::getTotal).reversed()).limit(5).collect(Collectors.toList());
        TopTotalInfoListResponse topTotalInfoListResponse = new TopTotalInfoListResponse();
        if (CollectionUtils.isEmpty(topLimit)) {
            return null;
        }
        List<TopTotalInfoResponse> topTotalInfoResponses = Lists.newArrayList();
        Integer colorCount = 0;
        //是否存在账款不足原因Lists.newArrayList("#FF6A00", "#1A7DFF", "#28C8D7", "#7561FD", "#7C99AA");
        Queue<String> colorQueue = new LinkedList<String>();
        colorQueue.offer("#1A7DFF");
        colorQueue.offer("#28C8D7");
        colorQueue.offer("#7561FD");
        colorQueue.offer("#7C99AA");
        Boolean isFlag = false;
        List<TopGroupCount> isFlagSize = topLimit.stream().filter(e->"账款不足".equals(e.getName())).collect(Collectors.toList());
        if(isFlagSize.size() > 0){
            isFlag = true;
        }
        for (TopGroupCount topGroupCount : topLimit) {
            String refuseReasonCode = topGroupCount.getCode();
            Integer sum = topGroupCount.getTotal();
            String name = topGroupCount.getName();
            TopTotalInfoResponse topTotalInfoResponse = new TopTotalInfoResponse();
            DataInfo value = getQuantityFormat(sum);
            if (sum >= 100000) {
                topTotalInfoResponse.setValue(value.getValue() + "万");
            } else {
                topTotalInfoResponse.setValue(value.getValue());
            }
            topTotalInfoResponse.setLabel(name);
            //账款不足高亮显示
            if(isFlag){
                if("账款不足".equals(name)){
                    topTotalInfoResponse.setColor("#FF6A00");
                }else{
                    String color = colorQueue.poll();
                    topTotalInfoResponse.setColor(color);
                }
            }else{
                topTotalInfoResponse.setColor(COLOR_LIST.get(colorCount));
            }

            topTotalInfoResponses.add(topTotalInfoResponse);
            colorCount++;
        }
        topTotalInfoListResponse.setList(topTotalInfoResponses);

        List<TopInfoDataShellResponse> topInfoDataShellResponses = Lists.newArrayList();
        List<TopInfoDataResponse> topInfoDataResponses = Lists.newArrayList();
        //处理部门维度的拒绝原因数据-------------------------------------------
        //根据部门维度分组
        List<String> topRefuseReason = topLimit.stream().map(TopGroupCount::getName).collect(Collectors.toList());
        Map<String, List<GetForecastQuantityResponse>> depMap =
                reasonIsNotNullList.stream().collect(Collectors.groupingBy(GetForecastQuantityResponse::getDepartmentCode));
        for (Map.Entry<String, List<GetForecastQuantityResponse>> entry : depMap.entrySet()) {
            //部门编码
            String depCode = entry.getKey();
            List<GetForecastQuantityResponse> depGroupList = entry.getValue();
            //部门维度再分组拒绝原因
            Map<String, List<GetForecastQuantityResponse>> refuseGroup =
                    depGroupList.stream().collect(Collectors.groupingBy(GetForecastQuantityResponse::getRefuseReasonCode));
            for (Map.Entry<String, List<GetForecastQuantityResponse>> refuse : refuseGroup.entrySet()) {
                List<GetForecastQuantityResponse> refuseList = refuse.getValue();
                //遍历拒绝原因维度的map
                TopInfoDataResponse topInfoDataResponse = new TopInfoDataResponse();
                //拒绝原因
                if (!topRefuseReason.contains(refuseList.get(0).getRefuseReason())) {
                    continue;
                }
                topInfoDataResponse.setColor(refuseList.get(0).getRefuseReason());
                //拒绝数量
                BigDecimal num = refuseList.stream().map(x->
                            calculateQuantity(x.getQuantity(),x.getUnitConvert()).subtract(calculateQuantity(x.getActualTotalReplyAmount(),x.getUnitConvert())))
                        .reduce(BigDecimal.ZERO,BigDecimal::add)
                        .setScale(0,BigDecimal.ROUND_HALF_UP);

                topInfoDataResponse.setValue(num.intValue());
                DataInfo numFormat = getQuantityFormat(num.intValue());
                if(num.intValue() > 100000){
                    topInfoDataResponse.setValueFormit(numFormat.getValue() + "万件");
                }else{
                    topInfoDataResponse.setValueFormit(numFormat.getValue() + "件");
                }
                topInfoDataResponse.setName(refuseList.get(0).getDepartmentName());
                topInfoDataResponse.setDepCode(depCode);
                refuseList.forEach(getForecastQuantityResponse ->
                        getForecastQuantityResponse.setAmount(
                                new BigDecimal(getForecastQuantityResponse.getQuantity()).multiply(getForecastQuantityResponse.getAmount())
                        )
                );
                BigDecimal  amount = refuseList.stream().map(GetForecastQuantityResponse::getAmount).
                        reduce(BigDecimal::add).orElse(new BigDecimal(0));
                if(amount.compareTo(new BigDecimal(0)) > 0){
                    amount = amount.divide(new BigDecimal(100),2, BigDecimal.ROUND_HALF_UP);
                }
                if(amount.compareTo(new BigDecimal(10000)) == -1){
                    //小于万元
                    topInfoDataResponse.setMoney(amount+"元");
                }else{
                    String amountStr = DomUtil.amountFormatWan(amount);
                    topInfoDataResponse.setMoney(amountStr + "万元");
                }
                topInfoDataResponses.add(topInfoDataResponse);
            }
        }
        //取前五
        /*List<TopInfoDataResponse> topInfoDataResponsesLimit =
                topInfoDataResponses.stream().sorted(Comparator.comparing(TopInfoDataResponse::getValue).
                        reversed()).limit(5).collect(Collectors.toList());*/

        Map<String, List<TopInfoDataResponse>> depGroupList =
                topInfoDataResponses.stream().collect(Collectors.groupingBy(TopInfoDataResponse::getDepCode));
        Integer flag = 1;
        List<TopInfoDataResponse> cacheList = Lists.newArrayList();
        //2022.12.21 所有部门的拒绝总数量进行一个排序
        Set<Map.Entry<String, List<TopInfoDataResponse>>> sortedDepGroupSet = depGroupList.entrySet().stream()
                .sorted(Comparator.comparing(stringListEntry -> {
                    int sum = stringListEntry.getValue().stream()
                            .map(TopInfoDataResponse::getValue)
                            .filter(Objects::nonNull)
                            .mapToInt(Integer::intValue).sum();
                    return -sum;
                })).collect(Collectors.toCollection(LinkedHashSet::new));
        for (Map.Entry<String, List<TopInfoDataResponse>> depGroup : sortedDepGroupSet) {
//        for (Map.Entry<String, List<TopInfoDataResponse>> depGroup : depGroupList.entrySet()) {
            List<TopInfoDataResponse> list = depGroup.getValue();
            List<TopInfoDataResponse> sortedList = list.stream().sorted(Comparator.comparing(TopInfoDataResponse::getValue)).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(cacheList)) {
                sortedList.addAll(cacheList);
                cacheList.clear();
            }
            cacheList.addAll(sortedList);
            if(flag % 2 == 0){
                TopInfoDataShellResponse shell = new TopInfoDataShellResponse();
                shell.setData(cacheList);
                topInfoDataShellResponses.add(shell);
                cacheList = Lists.newArrayList();
            }
            //最后一个单数
            if(depGroupList.size() == flag){
                TopInfoDataShellResponse shell = new TopInfoDataShellResponse();
                shell.setData(cacheList);
                topInfoDataShellResponses.add(shell);
            }
            flag++;
        }

        TopInfoDataListResponse topInfoDataListResponse = new TopInfoDataListResponse();
        topInfoDataListResponse.setList(topInfoDataShellResponses);

        QueryTopInfoResponse queryTopInfoResponse = new QueryTopInfoResponse();
        queryTopInfoResponse.setTopTotalInfoListResponse(topTotalInfoListResponse);
        queryTopInfoResponse.setTopInfoDataListResponse(topInfoDataListResponse);
        return queryTopInfoResponse;
    }

    /**
     * 渠道订单回复分析
     * @param queryChannelInfoRequest
     * @return
     */
    @Override
    public Result<QueryChannelInfoListResponse> queryChannelInfo(QueryChannelInfoRequest queryChannelInfoRequest) {
        String companyCode = getCompanyCode(queryChannelInfoRequest.getCompanyCode());
        String salesOrgId = getSalesOrgByCompanyOrgId(companyCode);
        //获取查询日期
        List<Date> dates = getThisFormatDate(queryChannelInfoRequest.getBeginDate(),queryChannelInfoRequest.getEndDate());
        //获取当天所有子单
        List<GetForecastQuantityResponse> subToday = querySubOrderList(salesOrgId, dates.get(0), dates.get(1));
        if(CollectionUtils.isEmpty(subToday)){
            return null;
        }
        QueryChannelInfoListResponse result = buildChannelInfo(subToday);
        return Result.success(result);
    }

    private QueryChannelInfoListResponse buildChannelInfo(List<GetForecastQuantityResponse> subToday) {
        if(CollectionUtils.isEmpty(subToday)){
            return null;
        }
        //根据渠道分组
        Map<String, List<GetForecastQuantityResponse>> map =
                subToday.stream().filter(x->StringUtils.isNotBlank(x.getChannelCode())).collect(Collectors.groupingBy(GetForecastQuantityResponse::getChannelCode));

        List<QueryChannelInfoDataResponse> channelInfoResponses = Lists.newArrayList();
        for (Map.Entry<String, List<GetForecastQuantityResponse>> entry : map.entrySet()) {
            List<GetForecastQuantityResponse> channelGroupList = entry.getValue();

            QueryChannelInfoDataResponse queryChannelInfoResponse = new QueryChannelInfoDataResponse();
            queryChannelInfoResponse.setChannelName(channelGroupList.get(0).getChannelName());
            //提报数量
            NumInfo quantityNumInfo = getQuantity(channelGroupList);
            queryChannelInfoResponse.setQuantity(quantityNumInfo.getValue());
            queryChannelInfoResponse.setApplyQuantity(quantityNumInfo.getNum());

            //待回复数量
            NumInfo waitNumInfo = getWaitNum(channelGroupList);
            queryChannelInfoResponse.setWaitNum(waitNumInfo.getValue());

            //已回复数量
            NumInfo finishNumInfo = getFinishNum(channelGroupList);
            queryChannelInfoResponse.setFinishNum(finishNumInfo.getValue());

            //拒绝数量
            NumInfo refuseNumInfo = getRefuseNum(channelGroupList);
            queryChannelInfoResponse.setRefuseNum(refuseNumInfo.getValue());

            //订单满足率,已回复数/提报数量
            String quantityFillRate = getFillRate(finishNumInfo.getNum(), quantityNumInfo.getNum());
            queryChannelInfoResponse.setOrderFillRate(quantityFillRate);
            channelInfoResponses.add(queryChannelInfoResponse);
        }
        QueryChannelInfoListResponse queryChannelInfoListResponse = new QueryChannelInfoListResponse();
        //2022.12.22 渠道订单回复分析 按提报数量倒序排
        if (CollectionUtils.isNotEmpty(channelInfoResponses)){
            Collections.sort(channelInfoResponses,
                    Comparator.comparing(QueryChannelInfoDataResponse::getApplyQuantity).reversed());
        }
        queryChannelInfoListResponse.setList(channelInfoResponses);
        return queryChannelInfoListResponse;
    }

    /**
     * 部门回复分析
     * @param queryDepInfoRequest
     * @return
     */
    @Override
    public Result<QueryDepInfoListResponse> queryDepInfo(QueryDepInfoRequest queryDepInfoRequest) {
        String companyCode = getCompanyCode(queryDepInfoRequest.getCompanyCode());
        String salesOrgId = getSalesOrgByCompanyOrgId(companyCode);
        //获取日期
        List<Date> dates = getThisFormatDate(queryDepInfoRequest.getBeginDate(),queryDepInfoRequest.getEndDate());
        //获取当天所有子单
        List<GetForecastQuantityResponse> subToday = querySubOrderList(salesOrgId, dates.get(0), dates.get(1));
        QueryDepInfoListResponse queryDepInfoResponse = buildDepInfo(subToday);
        return Result.success(queryDepInfoResponse);
    }

    private QueryDepInfoListResponse buildDepInfo(List<GetForecastQuantityResponse> subToday) {
        if(CollectionUtils.isEmpty(subToday)){
            return null;
        }
        //获取所有渠道，通过分组获取
        Map<String, List<GetForecastQuantityResponse>> map =
                subToday.stream().filter(x->StringUtils.isNotBlank(x.getChannelCode())).collect(Collectors.groupingBy(GetForecastQuantityResponse::getChannelCode));
        //遍历map获取所有渠道信息
        List<ChannelInfo> channelInfoList = Lists.newArrayList();
        for (Map.Entry<String, List<GetForecastQuantityResponse>> entry : map.entrySet()) {
            String code = entry.getKey();
            List<GetForecastQuantityResponse> list = entry.getValue();
            String name = list.get(0).getChannelName();
            ChannelInfo channelInfo = new ChannelInfo();
            channelInfo.setCode(code);
            channelInfo.setName(name);
            channelInfoList.add(channelInfo);
        }
        QueryDepInfoListResponse res = new QueryDepInfoListResponse();
        List<QueryDepInfoResponse> queryDepInfoListResponse = Lists.newArrayList();
        for (ChannelInfo channelInfo : channelInfoList) {
            QueryDepInfoResponse queryDepInfoResponse = new QueryDepInfoResponse();
            List<DepInfoResponse> depInfoResponses = Lists.newArrayList();
            //渠道名称
            queryDepInfoResponse.setTitle(channelInfo.getName());
            //通过渠道编码查询每个渠道下的所有预报单，并且使用部门进行分组
            List<GetForecastQuantityResponse> channelList =
                    subToday.stream().filter(e -> StringUtils.isNotBlank(e.getChannelCode()) && e.getChannelCode().equals(channelInfo.getCode())).collect(Collectors.toList());
            //根据部门分组
            Map<String, List<GetForecastQuantityResponse>> depMap =
                    channelList.stream().filter(x->StringUtils.isNotBlank(x.getDepartmentCode())).collect(Collectors.groupingBy(GetForecastQuantityResponse::getDepartmentCode));
            for (Map.Entry<String, List<GetForecastQuantityResponse>> entry : depMap.entrySet()) {
                List<GetForecastQuantityResponse> depList = entry.getValue();
                NumInfo finishNum = getFinishNum(depList);
                NumInfo quantity = getQuantity(depList);
                String quantityFillRate = getFillRate(finishNum.getNum(), quantity.getNum()) + "%";

                //提报数量
                DepInfoResponse quantityResponse = new DepInfoResponse();
                quantityResponse.setValue(quantity.getNum());
                quantityResponse.setValueFormit(quantity.getValue());
                quantityResponse.setName(depList.get(0).getDepartmentName());
                quantityResponse.setColor("提报数量（件）");
                quantityResponse.setPercent(quantityFillRate);
                depInfoResponses.add(quantityResponse);

                //待回复数量，状态是2和3，每一行的预报数量-累计数量
                DepInfoResponse waitResponse = new DepInfoResponse();
                NumInfo waitNum = getWaitNum(depList);
                waitResponse.setValueFormit(waitNum.getValue());
                waitResponse.setValue(waitNum.getNum());
                waitResponse.setPercent(quantityFillRate);
                waitResponse.setColor("待回复数量（件）");
                waitResponse.setName(depList.get(0).getDepartmentName());
                depInfoResponses.add(waitResponse);

                //已回复数量
                DepInfoResponse finishResponse = new DepInfoResponse();
                finishResponse.setValueFormit(finishNum.getValue());
                finishResponse.setValue(finishNum.getNum());
                finishResponse.setPercent(quantityFillRate);
                finishResponse.setColor("已回复数量（件）");
                finishResponse.setName(depList.get(0).getDepartmentName());
                depInfoResponses.add(finishResponse);

                //拒绝数量，状态是4，拒绝原因非空，预报数量-累计数量
                DepInfoResponse refuseResponse = new DepInfoResponse();
                NumInfo refuseNum = getRefuseNum(depList);
                refuseResponse.setValueFormit(refuseNum.getValue());
                refuseResponse.setValue(refuseNum.getNum());
                refuseResponse.setPercent(quantityFillRate);
                refuseResponse.setColor("已拒绝数量（件）");
                refuseResponse.setName(depList.get(0).getDepartmentName());
                depInfoResponses.add(refuseResponse);

//                //订单满足率,已回复数/提报数量
//                DepInfoResponse quantityFillRateResponse = new DepInfoResponse();

//                quantityFillRateResponse.setPercent(quantityFillRate);
//                depInfoResponses.add(quantityFillRateResponse);
            }
            queryDepInfoResponse.setData(depInfoResponses);
            queryDepInfoListResponse.add(queryDepInfoResponse);

            res.setList(queryDepInfoListResponse);
        }
        //2022.12.22 订单监控看板-渠道订单回复分子按照提报数量从大到小排序
        if (CollectionUtils.isNotEmpty(res.getList())){
            res.getList().forEach(response ->{
                if (CollectionUtils.isNotEmpty(response.getData())){
                    Collections.sort(response.getData(),(o1,o2) -> {
                        Integer v1 = o1.getValue() == null ? 0 : o1.getValue();
                        Integer v2 = o2.getValue() == null ? 0 : o2.getValue();
                        return v2.compareTo(v1);
                    });
                }
            });
        }
        return res;
    }

    /**
     * 日订单回复分析
     * @param queryDailyInfoRequest
     * @return
     */
    @Override
    @FacadeInvoker
    public Result<QueryDailyInfoResponse> queryDailyInfo(QueryDailyInfoRequest queryDailyInfoRequest) {
        String companyCode = getCompanyCode(queryDailyInfoRequest.getCompanyCode());
        String salesOrgId = getSalesOrgByCompanyOrgId(companyCode);
        QueryDailyInfoResponse queryDailyInfoResponse = buildDailyInfo(salesOrgId,queryDailyInfoRequest.getEndDate());
        return Result.success(queryDailyInfoResponse);
    }

    @FacadeInvoker
    private QueryDailyInfoResponse buildDailyInfo(String salesOrgId,String statisticalDate) {
        Date date = new Date();
        //获取本月及上月日期
        List<Integer> dateList = getYearAndMonth(date);
        Integer year = dateList.get(0);
        //当前月
        Integer currentMonth = dateList.get(1);
        //上个月
        Integer lastMonth = dateList.get(2);

        //获取当月所有日期
        List<String> currentMonthDate = getMonthFullDay(year, currentMonth);
        //当月开始日期
        String currentMonthBeginDate = currentMonthDate.get(0) + " 00:00:00";
        //当月结束日期
        String currentMonthEndDate = currentMonthDate.get(currentMonthDate.size() - 1) + " 23:59:59";
        //获取上月所有日期
        List<String> lastMonthDate = getMonthFullDay(year, lastMonth);
        //上月开始日期
        String lastMonthBeginDate = lastMonthDate.get(0) + " 00:00:00";
        //上月结束日期
        String lastMonthEndDate = lastMonthDate.get(lastMonthDate.size() - 1) + " 23:59:59";

        //获取当月所有子单
        List<GetForecastQuantityResponse> subCurrentMonth =
                querySubOrderList(salesOrgId, getDateFormat(currentMonthBeginDate), getDateFormat(currentMonthEndDate));
        log.info("buildDailyInfo.subCurrentMonth_size={}",subCurrentMonth.size());

        //获取上月所有子单
        List<GetForecastQuantityResponse> subLastMonth =
                querySubOrderList(salesOrgId, getDateFormat(lastMonthBeginDate), getDateFormat(lastMonthEndDate));
        log.info("buildDailyInfo.subLastMonth_size={}",subLastMonth.size());

        //计算当月
        List<DailyInfoResponse> currentMonthList = Lists.newArrayList();
        CurrentMonth currentMonthData = new CurrentMonth();
        if (CollectionUtils.isNotEmpty(subCurrentMonth)) {
            currentMonthDate.forEach(e -> {
                DailyInfoResponse current = new DailyInfoResponse();
                Date beginDate = getDateFormat(e + " 00:00:00");
                Date endDate = getDateFormat(e + " 23:59:59");
                //获取此日期内的所有符合要求的数据,并计算提报数量
                BigDecimal quantity = subCurrentMonth.stream().
                        filter(o -> ORDER_STATUS.contains(o.getMainStatus()) &&
                                Objects.nonNull(o.getVaildBeginTime()) &&
                                o.getVaildBeginTime().after(beginDate) &&
                                o.getVaildBeginTime().before(endDate))
                        .map(x->calculateQuantity(x.getQuantity(),x.getUnitConvert()))
                        .reduce(BigDecimal.ZERO,BigDecimal::add)
                        .setScale(0,BigDecimal.ROUND_HALF_UP);

                //当月当日提报量
                current.setNum(quantity.intValue());
//                DataInfo quantityDataInfo = getQuantityFormat(quantity);
//                if(quantity > 100000){
//                    current.setValue(quantityDataInfo.getValue() + "万件");
//                }else{
//                    current.setValue(quantityDataInfo.getValue() + "件");
//                }
                current.setValue(fmtMicrometer(quantity + "") + "件");
                currentMonthList.add(current);
            });
            currentMonthData.setList(currentMonthList);
        }else{
            currentMonthDate.forEach(e->{
                DailyInfoResponse current = new DailyInfoResponse();
                current.setNum(0);
                current.setValue(fmtMicrometer("0") + "件");
                currentMonthList.add(current);
            });
        }
        log.info("buildDailyInfo.currentMonthList {}",JSONObject.toJSONString(currentMonthList));

        //上月统计值
        List<DailyInfoResponse> monthLastList = Lists.newArrayList();
        LastMonth lastMonthData = new LastMonth();
        if (CollectionUtils.isNotEmpty(subLastMonth)) {
            lastMonthDate.forEach(e -> {
                DailyInfoResponse last = new DailyInfoResponse();
                Date beginDate = getDateFormat(e + " 00:00:00");
                Date endDate = getDateFormat(e + " 23:59:59");
                //获取此日期内的所有符合要求的数据,并计算提报数量
                BigDecimal quantity = subLastMonth.stream().
                        filter(o -> ORDER_STATUS.contains(o.getMainStatus()) &&
                                Objects.nonNull(o.getVaildBeginTime()) &&
                                o.getVaildBeginTime().after(beginDate) &&
                                o.getVaildBeginTime().before(endDate))
                        .map(x->calculateQuantity(x.getQuantity(),x.getUnitConvert()))
                        .reduce(BigDecimal.ZERO,BigDecimal::add)
                        .setScale(0,BigDecimal.ROUND_HALF_UP);
                //当月当日提报量
                last.setNum(quantity.intValue());
//                DataInfo quantityDataInfo = getQuantityFormat(quantity);
//                if(quantity > 100000){
//                    last.setValue(quantityDataInfo.getValue() + "万件");
//                }else{
//                    last.setValue(quantityDataInfo.getValue() + "件");
//                }
                last.setValue(fmtMicrometer(quantity + "") + "件");
                monthLastList.add(last);
            });
            lastMonthData.setList(monthLastList);
        }else{
            lastMonthDate.forEach(e->{
                DailyInfoResponse last = new DailyInfoResponse();
                last.setNum(0);
                last.setValue(fmtMicrometer("0") + "件");
                monthLastList.add(last);
            });
        }

        log.info("buildDailyInfo.lastMonthList {}",JSONObject.toJSONString(monthLastList));
        QueryDailyInfoResponse queryDailyInfoResponse = new QueryDailyInfoResponse();
        queryDailyInfoResponse.setCurrentMonth(currentMonthData);
        queryDailyInfoResponse.setLastMonth(lastMonthData);
        queryDailyInfoResponse.setStatisticalDate(statisticalDate);
        return queryDailyInfoResponse;
    }

    /**
     * 计算订单满足率 已回复数/提报数量
     *
     * @param divisor  除数
     * @param dividend 被除数
     * @return
     */
    private String getFillRate(Integer divisor, Integer dividend) {
        if (new Integer(0).equals(dividend)) {
            return "100.00";
        }
        if (new Integer(0).equals(divisor)) {
            return "0.00";
        }
        BigDecimal result = new BigDecimal(divisor).
                divide(new BigDecimal(dividend), 4, BigDecimal.ROUND_HALF_UP);
        return result.multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP) + "";
    }

    private CompareInfo getCompareValue(Integer today, Integer yesterday) {
        CompareInfo compareInfo = new CompareInfo();
        if (new Integer(0) >= yesterday
                && new Integer(0) < today) {
            //昨天0条记录，且今天大于0条，直接返回100%
            compareInfo.setValue("100.00%");
            compareInfo.setUnit(1);
            return compareInfo;
        }
        if (new Integer(0) >= yesterday &&
                new Integer(0) >= yesterday) {
            //两天都是0条记录
            compareInfo.setValue("0.00%");
            compareInfo.setUnit(0);
            return compareInfo;
        }
        if (new Integer(0) >= today &&
                new Integer(0) < yesterday) {
            //今天是0条，昨天大于0
            compareInfo.setValue("-100.00%");
            compareInfo.setUnit(-1);
            return compareInfo;
        }
        BigDecimal subList = (new BigDecimal(Objects.isNull(today) ? 0 : today).subtract(new BigDecimal(Objects.isNull(yesterday) ? 0 : yesterday)));
        BigDecimal result = subList.divide(new BigDecimal(yesterday), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).
                setScale(2, BigDecimal.ROUND_HALF_UP);
        compareInfo.setValue(result + "%");
        if (result.compareTo(BigDecimal.ZERO) > 0) {
            compareInfo.setUnit(1);
        }
        if (result.compareTo(BigDecimal.ZERO) < 0) {
            compareInfo.setUnit(-1);
        }
        if (result.compareTo(BigDecimal.ZERO) == 0) {
            compareInfo.setUnit(0);
        }
        return compareInfo;
    }

    private List<OfsForecastOrderIndex> queryMainOrderList(String code, Date beginDate, Date endDate) {
        SearchForecastOrderRequest request = new SearchForecastOrderRequest();
        //request.setMainBisUnitCode(code);
        request.setOrganizationCodeList(Lists.newArrayList(code));
        request.setValidStartDate(beginDate);
        request.setValidEndDate(endDate);
        request.setMainStatusList(ORDER_STATUS);
        request.setStart(0);
        request.setLimit(1000);
        Result<List<OfsForecastOrderIndex>> listResult = ofsForecastOrderIndexService.queryForecastOrderListForReport(request);
        log.info("view_queryMainOrderList_queryForecastOrderListForReport_size={}",listResult.getTotal());
        if (Objects.isNull(listResult)) {
            return null;
        }
        Integer total = listResult.getTotal();
        if (total <= 1000) {
            return listResult.getResult();
        }

        List<OfsForecastOrderIndex> result = Lists.newArrayList();
        result.addAll(listResult.getResult());

        Integer page = total / 1000;
        if (total % 1000 > 0) {
            page = page + 1;
        }
        for (int i = 1; i < page; i++) {
            request.setStart(i*1000);
            Result<List<OfsForecastOrderIndex>> list = ofsForecastOrderIndexService.queryForecastOrderListForReport(request);
            if (Objects.isNull(list)) {
                continue;
            }
            List<OfsForecastOrderIndex> ofsForecastOrderIndexs = list.getResult();
            if (CollectionUtils.isEmpty(ofsForecastOrderIndexs)) {
                continue;
            }
            result.addAll(ofsForecastOrderIndexs);
        }
        return result;
    }

    private List<GetForecastQuantityResponse> querySubOrderList(String code, Date beginDate, Date endDate) {
        SearchForecastOrderRequest request = new SearchForecastOrderRequest();
        //request.setMainBisUnitCode(code);
        request.setOrganizationCodeList(Lists.newArrayList(code));
        request.setValidStartDate(beginDate);
        request.setValidEndDate(endDate);
        //这个查询接口查所有预报子单
        Result<GetForecastQuantityListResponse> listResult = forecastOrderLineQueryService.queryForecastOrderLinesForReport(request);
        Integer total = Objects.nonNull(listResult) && CollectionUtils.isNotEmpty(listResult.getResult().getList())?listResult.getResult().getList().size():0;
        log.info("view_querySubOrderList_queryForecastOrderLinesForReport_size={}",total);
        if (total == 0) {
            return new ArrayList<>();
        }
        return listResult.getResult().getList();
//        if (total <= 1000) {
//            return listResult.getResult().getList();
//        }
//        List<GetForecastQuantityResponse> result = Lists.newArrayList();
//        result.addAll(listResult.getResult().getList());
//
//        Integer page = total / 1000;
//        if (total % 1000 > 0) {
//            page = page + 1;
//        }
//        for (int i = 1; i < page; i++) {
//            request.setStart(i*1000);
//            Result<GetForecastQuantityListResponse> list = forecastOrderLineQueryService.queryForecastOrderLinesForReport(request);
//            if (Objects.isNull(list)) {
//                continue;
//            }
//            List<GetForecastQuantityResponse> getForecastQuantityList = list.getResult().getList();
//            if (CollectionUtils.isEmpty(getForecastQuantityList)) {
//                continue;
//            }
//            result.addAll(getForecastQuantityList);
//        }
//        return result;
    }

//    private List<GetForecastQuantityResponse> getForecastQuantityListForReport(
//            Date vaildBeginTime, Date vaildEndTime, String companyCode, String channelCode) {
//        GetForecastQuantityListForReportRequest request = new GetForecastQuantityListForReportRequest();
//        request.setCompanyCode(companyCode);
//        request.setVaildBeginTime(vaildBeginTime);
//        request.setVaildEndTime(vaildEndTime);
//        request.setChannelCode(channelCode);
//        Result<GetForecastQuantityListResponse> forecastQuantityListForReport =
//                otsForecastSalesService.getForecastQuantityListForReport(request);
//        if (Objects.isNull(forecastQuantityListForReport)) {
//            return null;
//        }
//        GetForecastQuantityListResponse getForecastQuantityListResponse =
//                forecastQuantityListForReport.getResult();
//        if (Objects.isNull(getForecastQuantityListResponse)) {
//            return null;
//        }
//        return getForecastQuantityListResponse.getList();
//    }

//    private com.epoch.app.bcorder.model.dto.OrganizationSDO getOrgById(String id) {
//        SalesPlanGetChildrenOrgRequest request = new SalesPlanGetChildrenOrgRequest();
//        request.setOrganizationId(id);
//        SalesPlanGetChildrenOrgResponse response = baseDataService.salesPlanGetChildrenOrg(request);
//        if (Objects.isNull(response)) {
//            return null;
//        }
//        List<com.epoch.app.bcorder.model.dto.OrganizationSDO> list = response.getResult();
//        if (CollectionUtils.isEmpty(list)) {
//            return null;
//        }
//        return list.get(0);
//    }

    private String setCompanyInfo() {
        CompanySDO companyInfo = getCompanyInfo();
        OrganizationSDO organizationSDO = getOrgInfo();
        if (Objects.isNull(companyInfo) || Objects.isNull(organizationSDO)) {
            throw new IllegalArgumentException("未查询到组织");
        }
        return organizationSDO.getId();
//        List<OrganizationSDO> organizationSDOS = getBranchCompanyList();
//        String companyName = getBranchCompanyName(organizationSDOS, companyCode);
//        if (CollectionUtils.isEmpty(organizationSDOS) || StringUtils.isBlank(companyName)) {
//            throw new IllegalArgumentException("未查询到组织信息");
//        }
//        forecastOrderReportsResponse.setCompanyId(companyCode);
//        forecastOrderReportsResponse.setCompanyName(companyName);
//        return queryOrderInfoRequest.getCompanyCode();
    }

//    private String getBranchCompanyName(List<OrganizationSDO> organizationSDOS, String branchCompanyId) {
//        for (OrganizationSDO sdo : organizationSDOS) {
//            if (sdo.getId().equals(branchCompanyId)) {
//                return sdo.getName();
//            }
//        }
//        return null;
//    }
//
//    private CompanySDO getCompanyInfoByCode(String code) {
//        BatchQueryCompany2Request request = new BatchQueryCompany2Request();
//        List<String> codes = Lists.newArrayList();
//        codes.add(code);
//        request.setCodes(codes);
//        Result<List<CompanySDO>> companySDOResult = bcOtsService.batchQueryCompany2(request);
//        if (Objects.isNull(companySDOResult)) {
//            return null;
//        }
//        List<CompanySDO> companySDOList = companySDOResult.getResult();
//        if (CollectionUtils.isEmpty(companySDOList)) {
//            return null;
//        }
//        return companySDOList.get(0);
//    }

    private OrganizationSDO getOrgInfo() {
        Result<List<OrganizationSDO>> org = otsPlatformEnhanceService.getLoginEmployeeBusinessUnitsSort();
        log.info("getOrgInfo org" + JSONObject.toJSONString(org));
        if (Objects.isNull(org)) {
            return null;
        }
        List<OrganizationSDO> list = org.getResult();
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        return list.get(0);
    }

    private CompanySDO getCompanyInfo() {
        Result<List<OrganizationSDO>> org = otsPlatformEnhanceService.getLoginEmployeeBusinessUnitsSort();
        log.info("getCompanyInfo orgList =", JSONObject.toJSONString(org));
        if (Objects.isNull(org)) {
            return null;
        }
        List<OrganizationSDO> list = org.getResult();
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }

        OrganizationSDO organizationSDO = list.get(0);
        if (StringUtils.isBlank(organizationSDO.getBizId())) {
            return null;
        }
        BatchQueryCompany2Request request = new BatchQueryCompany2Request();
        List<String> ids = Lists.newArrayList();
        ids.add(organizationSDO.getBizId());
        request.setIds(ids);
        Result<List<CompanySDO>> companySDOResult = bcOtsService.batchQueryCompany2(request);
        log.info("getCompanyInfo companySDOResult =", JSONObject.toJSONString(companySDOResult));
        if (Objects.isNull(companySDOResult)) {
            return null;
        }
        List<CompanySDO> companySDOList = companySDOResult.getResult();
        if (CollectionUtils.isEmpty(companySDOList)) {
            return null;
        }
        return companySDOList.get(0);
    }

    private String[] getProportionOfReplies(Integer orders, Integer repliesOrders) {
        BigDecimal order = new BigDecimal(Objects.isNull(orders) ? 0 : orders);
        BigDecimal repliesOrder = new BigDecimal(Objects.isNull(repliesOrders) ? 0 : repliesOrders);
        if (new Integer(0) >= (order.compareTo(new BigDecimal(0))) &&
                new Integer(0) < (repliesOrder.compareTo(new BigDecimal(0)))) {
            //订单数小于等于0，且回复单数大于等于0的，直接返回100.00%
            return "100.00".split("\\.");
        }

        if (new Integer(0) < (order.compareTo(new BigDecimal(0))) &&
                new Integer(0) >= (repliesOrder.compareTo(new BigDecimal(0)))) {
            //订单数大于0，且回复单数小于等于0的，直接返回0.00
            return "0.00".split("\\.");
        }

        if (new BigDecimal(0).equals(repliesOrder) && new BigDecimal(0).equals(order)) {
            return "0.00".split("\\.");
        }
        BigDecimal divideResult = repliesOrder.
                divide(order, 4, BigDecimal.ROUND_HALF_UP);
        BigDecimal result = divideResult.multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
        return result.toString().split("\\.");
    }

    private DataInfo getQuantityFormatForForecastOrder(Integer size) {
        return DomUtil.quantityFormatForForecastOrder(Long.valueOf(size));
    }

    private DataInfo getQuantityFormat(Integer size) {
        return DomUtil.quantityFormatForJian(Long.valueOf(size));
    }

    private DataInfo getMoneyFormat(BigDecimal money) {
        return DomUtil.moneyFormatForYuan(money);
    }

    private List<Date> getYesterdaysDateFormat(Date statisticalDate) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(statisticalDate !=null?statisticalDate:new Date());
        calendar.add(calendar.DATE, -1);
        String date = sdf.format(calendar.getTime());
        String start = " 00:00:00";
        String end = " 23:59:59";
        List<Date> dates = Lists.newArrayList();
        try {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            dates.add(0, format.parse(date + start));
            dates.add(1, format.parse(date + end));
        } catch (ParseException p) {
            p.printStackTrace();
        }
        return dates;
    }

    private List<Date> getTodayFormatDate(Date statisticalDate) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String date = sdf.format(statisticalDate !=null?statisticalDate:new Date());
        String start = " 00:00:00";
        String end = " 23:59:59";
        List<Date> dates = Lists.newArrayList();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        try {
            dates.add(0, format.parse(date + start));
            dates.add(1, format.parse(date + end));
        } catch (ParseException p) {
            p.printStackTrace();
        }
        return dates;
    }

    private List<Date> getThisFormatDate(String begin,String end) {
        List<Date> dates = Lists.newArrayList();
        if(StringUtils.isNotBlank(begin) && StringUtils.isNotBlank(end)){
            String beginDate = DateUtils.toDateStr(DateUtils.parse(begin),DateUtils.DATE_FORMAT);
            String endDate = DateUtils.toDateStr(DateUtils.parse(end),DateUtils.DATE_FORMAT);
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            try {
                dates.add(0, format.parse(beginDate + " 00:00:00"));
                dates.add(1, format.parse(endDate + " 23:59:59"));
            } catch (ParseException p) {
                p.printStackTrace();
            }
        }else{
            dates = getTodayFormatDate(null);
        }
        return dates;
    }

    private List<Date> getLastFormatDate(String begin,String end) {
        List<Date> dates = Lists.newArrayList();
        if(StringUtils.isNotBlank(begin) && StringUtils.isNotBlank(end)){
            Date beginDate = DateUtils.parse(begin);
            Date endDate = DateUtils.parse(end);
            long between_days = (endDate.getTime()-beginDate.getTime())/(1000*3600*24);
            int rollback_days = (int)(between_days+1)*-1;
            String lastBegin = DomUtil.getRollbackDate(beginDate,rollback_days);
            String lastEnd = DomUtil.getRollbackDate(beginDate,-1);
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            try {
                dates.add(0, format.parse(lastBegin + " 00:00:00"));
                dates.add(1, format.parse(lastEnd + " 23:59:59"));
            } catch (ParseException p) {
                p.printStackTrace();
            }
        }else{
            dates = getYesterdaysDateFormat(null);
        }
        return dates;
    }

    public String fmtMicrometer(String text) {
        DecimalFormat df = null;
        if (text.indexOf(".") > 0) {
            if (text.length() - text.indexOf(".") - 1 == 0) {
                df = new DecimalFormat("###,##0.");
            } else if (text.length() - text.indexOf(".") - 1 == 1) {
                df = new DecimalFormat("###,##0.0");
            } else {
                df = new DecimalFormat("###,##0.00");
            }
        } else {
            df = new DecimalFormat("###,##0");
        }
        double number = 0.0;
        try {
            number = Double.parseDouble(text);
        } catch (Exception e) {
            number = 0.0;
        }
        return df.format(number);
    }

    private List<Integer> getYearAndMonth(Date date) {
        SimpleDateFormat dateFormatYYYYMMDD = new SimpleDateFormat("yyyy-MM");
        String dateStr = dateFormatYYYYMMDD.format(date);
        String[] dataArray = dateStr.split("-");
        String year = dataArray[0];
        String month = dataArray[1];
        //上个月
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -1); // 设置为上一个月
        date = calendar.getTime();
        String accDate = dateFormatYYYYMMDD.format(date);
        String[] accDateArray = accDate.split("-");
        String beforeMonth = accDateArray[1];

        List<Integer> result = Lists.newArrayList();
        result.add(0, Integer.valueOf(year));
        result.add(1, Integer.valueOf(month));
        result.add(2, Integer.valueOf(beforeMonth));
        return result;
    }

    public List<String> getMonthFullDay(int year, int month) {
        SimpleDateFormat dateFormatYYYYMMDD = new SimpleDateFormat("yyyy-MM-dd");
        List<String> fullDayList = new ArrayList<>(32);
        // 获得当前日期对象
        Calendar cal = Calendar.getInstance();
        cal.clear();// 清除信息
        cal.set(Calendar.YEAR, year);
        // 1月从0开始
        cal.set(Calendar.MONTH, month - 1);
        // 当月1号
        cal.set(Calendar.DAY_OF_MONTH, 1);
        int count = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        for (int j = 1; j <= count; j++) {
            fullDayList.add(dateFormatYYYYMMDD.format(cal.getTime()));
            cal.add(Calendar.DAY_OF_MONTH, 1);
        }
        return fullDayList;
    }

    private NumInfo getQuantity(List<GetForecastQuantityResponse> list) {
        BigDecimal quantity = list.stream()
                .filter(o -> ORDER_STATUS.contains(o.getMainStatus())
                        && ORDER_STATUS.contains(o.getDetailStatus())
                ).map(x->calculateQuantity(x.getQuantity(),x.getUnitConvert()))
                .reduce(BigDecimal.ZERO,BigDecimal::add)
                .setScale(0,BigDecimal.ROUND_HALF_UP);
        String quantityFormat = fmtMicrometer(quantity + "");
        NumInfo numInfo = new NumInfo();
        numInfo.setNum(quantity.intValue());
        numInfo.setValue(quantityFormat);
        return numInfo;
    }

    private Map<String,NumInfo> getQuantityAndMoney(List<GetForecastQuantityResponse> list) {
        Map<String,NumInfo> result = new HashMap();
        List<GetForecastQuantityResponse> filterList = list.stream().filter(o ->
                ORDER_STATUS.contains(o.getMainStatus())&& ORDER_STATUS.contains(o.getDetailStatus())
            ).collect(Collectors.toList());
        //计算提报量
        BigDecimal quantity = filterList.stream()
                .map(x->calculateQuantity(x.getQuantity(),x.getUnitConvert()))
                .reduce(BigDecimal.ZERO,BigDecimal::add)
                .setScale(0,BigDecimal.ROUND_HALF_UP);
        String quantityFormat = fmtMicrometer(quantity + "");
        NumInfo numInfo = new NumInfo();
        numInfo.setNum(quantity.intValue());
        numInfo.setValue(quantityFormat);
        result.put("quantity",numInfo);
        //计算订单金额
        BigDecimal money = filterList.stream()
                .map(x->x.getTotalAmount())
                .reduce(BigDecimal.ZERO,BigDecimal::add)
                .setScale(0,BigDecimal.ROUND_HALF_UP);
        money = money.divide(new BigDecimal(100),2,BigDecimal.ROUND_HALF_UP);
        String moneyFormat = fmtMicrometer(money + "");
        NumInfo numInfo2 = new NumInfo();
        numInfo2.setMoney(money);
        numInfo2.setValue(moneyFormat);
        result.put("money",numInfo2);
        return result;
    }

    private NumInfo getWaitNum(List<GetForecastQuantityResponse> list) {
        //状态是2和3，每一行的预报数量-累计数量
        List<GetForecastQuantityResponse> waitNumList = list.stream()
                .filter(o -> WAIT_ORDER_STATUS.contains(o.getMainStatus())
                        && WAIT_ORDER_STATUS.contains(o.getDetailStatus())
                        && Objects.nonNull(o.getActualTotalReplyAmount())
                ).collect(Collectors.toList());
        BigDecimal waitNum = waitNumList.stream().map(x->
                        calculateQuantity(x.getQuantity(),x.getUnitConvert()).subtract(calculateQuantity(x.getActualTotalReplyAmount(),x.getUnitConvert())))
                .reduce(BigDecimal.ZERO,BigDecimal::add)
                .setScale(0,BigDecimal.ROUND_HALF_UP);
        String waitNumDataInfo = fmtMicrometer(waitNum + "");
        NumInfo numInfo = new NumInfo();
        numInfo.setNum(waitNum.intValue());
        numInfo.setValue(waitNumDataInfo);
        return numInfo;
    }

    private Map<String,NumInfo> getWaitNumAndMoney(List<GetForecastQuantityResponse> list) {
        Map<String,NumInfo> result = new HashMap();
        //状态是2和3，每一行的预报数量-累计数量
        List<GetForecastQuantityResponse> filterList = list.stream()
                .filter(o -> WAIT_ORDER_STATUS.contains(o.getMainStatus())
                        && WAIT_ORDER_STATUS.contains(o.getDetailStatus())
                        && Objects.nonNull(o.getActualTotalReplyAmount())
                ).collect(Collectors.toList());
        //计算待回复量
        BigDecimal waitNum = filterList.stream().map(x->
                        calculateQuantity(x.getQuantity(),x.getUnitConvert()).subtract(calculateQuantity(x.getActualTotalReplyAmount(),x.getUnitConvert())))
                .reduce(BigDecimal.ZERO,BigDecimal::add)
                .setScale(0,BigDecimal.ROUND_HALF_UP);
        String waitNumDataInfo = fmtMicrometer(waitNum + "");
        NumInfo numInfo = new NumInfo();
        numInfo.setNum(waitNum.intValue());
        numInfo.setValue(waitNumDataInfo);
        result.put("quantity",numInfo);
        //计算待回复金额
        BigDecimal money = filterList.stream()
                .map(x-> { return x.getAmount().multiply(new BigDecimal(x.getQuantity()-x.getActualTotalReplyAmount())); })
                .reduce(BigDecimal.ZERO,BigDecimal::add)
                .setScale(0,BigDecimal.ROUND_HALF_UP);
        money = money.divide(new BigDecimal(100),2,BigDecimal.ROUND_HALF_UP);
        String moneyFormat = fmtMicrometer(money + "");
        NumInfo numInfo2 = new NumInfo();
        numInfo2.setMoney(money);
        numInfo2.setValue(moneyFormat);
        result.put("money",numInfo2);
        return result;
    }

    private NumInfo getFinishNum(List<GetForecastQuantityResponse> list) {
        //主单状态是3，4，每一行的累计数量
        BigDecimal finishNum = list.stream()
                .filter(o -> FINISH_ORDER_STATUS.contains(o.getMainStatus())
                        && FINISH_ORDER_STATUS.contains(o.getDetailStatus())
                        && Objects.nonNull(o.getActualTotalReplyAmount())
                ).map(x->calculateQuantity(x.getActualTotalReplyAmount(),x.getUnitConvert()))
                .reduce(BigDecimal.ZERO,BigDecimal::add)
                .setScale(0,BigDecimal.ROUND_HALF_UP);
        String finishNumDataInfo = fmtMicrometer(finishNum + "");
        NumInfo numInfo = new NumInfo();
        numInfo.setNum(finishNum.intValue());
        numInfo.setValue(finishNumDataInfo);
        return numInfo;
    }

    private Map<String,NumInfo> getFinishNumAndMoney(List<GetForecastQuantityResponse> list) {
        Map<String,NumInfo> result = new HashMap();
        //主单状态是3，4，每一行的累计数量
        List<GetForecastQuantityResponse> filterList = list.stream()
                .filter(o -> FINISH_ORDER_STATUS.contains(o.getMainStatus())
                        && FINISH_ORDER_STATUS.contains(o.getDetailStatus())
                        && Objects.nonNull(o.getActualTotalReplyAmount())
                ).collect(Collectors.toList());
        //计算已回复量
        BigDecimal finishNum = filterList.stream()
                .map(x->calculateQuantity(x.getActualTotalReplyAmount(),x.getUnitConvert()))
                .reduce(BigDecimal.ZERO,BigDecimal::add)
                .setScale(0,BigDecimal.ROUND_HALF_UP);
        String finishNumDataInfo = fmtMicrometer(finishNum + "");
        NumInfo numInfo = new NumInfo();
        numInfo.setNum(finishNum.intValue());
        numInfo.setValue(finishNumDataInfo);
        result.put("quantity",numInfo);
        //计算已回复金额
        BigDecimal money = filterList.stream()
                .map(x-> { return x.getAmount().multiply(new BigDecimal(x.getActualTotalReplyAmount())); })
                .reduce(BigDecimal.ZERO,BigDecimal::add)
                .setScale(0,BigDecimal.ROUND_HALF_UP);
        money = money.divide(new BigDecimal(100),2,BigDecimal.ROUND_HALF_UP);
        String moneyFormat = fmtMicrometer(money + "");
        NumInfo numInfo2 = new NumInfo();
        numInfo2.setMoney(money);
        numInfo2.setValue(moneyFormat);
        result.put("money",numInfo2);
        return result;
    }

    private NumInfo getRefuseNum(List<GetForecastQuantityResponse> list) {
        //状态是4，拒绝原因非空，预报数量-累计数量
        List<GetForecastQuantityResponse> refuseNumList = list.stream().
                filter(o -> REFUSE_ORDER_STATUS.contains(o.getMainStatus())
                        && REFUSE_ORDER_STATUS.contains(o.getDetailStatus())
                        && Objects.nonNull(o.getRefuseReasonCode())
                        && Objects.nonNull(o.getActualTotalReplyAmount())
                ).collect(Collectors.toList());
        //计算预报数量-累计数量
        List<BigDecimal> quantityList = refuseNumList.stream().map(x->
                        calculateQuantity(x.getQuantity(),x.getUnitConvert()).subtract(calculateQuantity(x.getActualTotalReplyAmount(),x.getUnitConvert())))
                .collect(Collectors.toList());
//        refuseNumList.forEach(getForecastQuantityResponse ->
//                getForecastQuantityResponse.setQuantity(
//                        getForecastQuantityResponse.getQuantity() - getForecastQuantityResponse.getActualTotalReplyAmount()
//                )
//        );
        //求累加值
        BigDecimal refuseNum = quantityList.stream().reduce(BigDecimal.ZERO,BigDecimal::add).setScale(0,BigDecimal.ROUND_HALF_UP);
        String refuseNumDataInfo = fmtMicrometer(refuseNum + "");
        NumInfo numInfo = new NumInfo();
        numInfo.setNum(refuseNum.intValue());
        numInfo.setValue(refuseNumDataInfo);
        return numInfo;
    }

    private BigDecimal calculateQuantity(Integer quantity, String unitConvert){
        if(quantity == null){
            return BigDecimal.ZERO;
        }
        if(!"1".equals(unitConvert)){
            BigDecimal jian = new BigDecimal(quantity).divide(new BigDecimal(unitConvert),1,BigDecimal.ROUND_HALF_UP);
            return jian;
        }
        return new BigDecimal(quantity);
    }

//    private Boolean filterNotRefuseOrder(GetForecastQuantityResponse sdo){
//        return org.apache.commons.lang3.StringUtils.isBlank(sdo.getRefuseReason()) && org.apache.commons.lang3.StringUtils.isBlank(sdo.getRefuseReasonCode());
//    }

    private Date getDateFormat(String date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd hh:mm:ss");
        Date formatDate = null;
        try {
            formatDate = sdf.parse(date);
        } catch (ParseException p) {
            log.error(p.getMessage());
        }
        return formatDate;
    }

    private String getCompanyCode(String code){
        String companyCode = null;
        if(StringUtils.isBlank(code)){
            companyCode = setCompanyInfo();
        }else{
            companyCode = code;
        }
        return companyCode;
    }

    private String getSalesOrgByCompanyOrgId(String id){
        GetDownOrganizationListRequest getDownOrganizationListRequest = new GetDownOrganizationListRequest();
        getDownOrganizationListRequest.setId(id);
        getDownOrganizationListRequest.setType(OrganizationTypeEnum.SALES_ORGANIZATION.getCode());
        Result<List<OrganizationSDO>> organizationResult = otsPlatformEnhanceService.getDownOrganizationList(getDownOrganizationListRequest);
        if(organizationResult== null || CollectionUtils.isEmpty(organizationResult.getResult())){
            throw new FacadeException("OTS-01-003-01-15-012");
        }
        List<OrganizationSDO> filterList = organizationResult.getResult().stream().filter(x->x.getName().contains("销售组织")).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(filterList)){
            throw new FacadeException("OTS-01-003-01-15-012");
        }
        return filterList.get(0).getId();
    }

    @Data
    class TopGroupCount {
        //拒绝原因编码
        private String code;
        //拒绝原因名称
        private String name;
        //拒绝原因统计数量
        private Integer total;
    }

    @Data
    class NumInfo {
        private Integer num;
        private BigDecimal money;
        private String value;
    }

    @Data
    class CompareInfo {
        private String value;
        //1:今天增长，0:两天持平，-1:少于昨天
        private Integer unit;
    }

    @Data
    class ChannelInfo {
        private String code;
        private String name;
    }

    private ForecastOrderReportsResponse mockData() {
        List<String> names = Lists.newArrayList("订单回复", "超计划量", "调拨回复", "价格差异", "超活动量", "订单回复", "超计划量", "调拨回复", "价格差异", "超活动量");
        ForecastOrderReportsResponse res = new ForecastOrderReportsResponse();
        List<ForecastOrderReportsTopListResponse> list = Lists.newArrayList();
        List<ForecastOrderReportsTopNumResponse> ForecastOrderReportsTopNumList = Lists.newArrayList();
        for (int i = 0; i < 10; i++) {
            ForecastOrderReportsTopListResponse top = new ForecastOrderReportsTopListResponse();
//            top.setKey((i < 5) ? "未回复原因" : "全部未回复");
//            top.setName(names.get(i));
//            top.setNum("1234" + i + "件");
//            top.setPercent(new BigDecimal(50.00));
            list.add(top);
        }

        for (int i = 0; i < 5; i++) {
            ForecastOrderReportsTopNumResponse topNum = new ForecastOrderReportsTopNumResponse();
            topNum.setName("价格差异");
            topNum.setNum("15233件");
            ForecastOrderReportsTopNumList.add(topNum);
        }

        res.setForecastOrderReportsTopList(list);
        res.setOrdersSize("20,000");
        res.setOrdersSizeUnit("单");
        res.setOrderDetailsCompare("+1.50%");
        res.setRepliedOrderSize("18,000");
        res.setRepliedOrderSizeCompare("-1.50%");
        res.setRepliedOrderSizeUnit("单");
        res.setOrdersProportionOfReplies("90");
        res.setOrdersSizeSign("1");
        res.setRepliedOrderSizeSign("-1");
        res.setOrderSizeTail(".00%");
        res.setOrderDetailsSize("30,000");
        res.setOrderDetailsSizeUnit("件");
        res.setOrderDetailsCompare("+1.50%");
        res.setRepliedOrderDetailsSize("21,000");
        res.setRepliedOrderDetailsSizeUnit("件");
        res.setOrderDetailsCompare("-1.50%");
        res.setOrderDetailsProportionOfReplies("70");
        res.setOrderDetailsSizeSign("1");
        res.setRepliedOrderDetailsSizeSign("-1");
        res.setOrderDetailTail(".01%");
        res.setForecastOrderReportsTopNumList(ForecastOrderReportsTopNumList);
        return res;
    }

    @Override
    @FacadeInvoker
    public Result<ForecastOrderReportsResponse> forecastOrderReportsQuery(ForecastOrderReportsQueryRequest forecastOrderReportsQueryRequest) {
        log.info("forecastOrderReportsQuery version-0-1 request {}", JSONObject.toJSONString(forecastOrderReportsQueryRequest));
        ForecastOrderReportsResponse forecastOrderReportsResponse = new ForecastOrderReportsResponse();

//        try {
////            String companyCode = setCompanyInfo(forecastOrderReportsQueryRequest.getCompanyCode(), forecastOrderReportsResponse, forecastOrderReportsQueryRequest);
//            companyCode = StringUtils.isNotBlank(forecastOrderReportsQueryRequest.getCompanyCode())
//                    ? forecastOrderReportsQueryRequest.getCompanyCode() : companyCode;
//            //主单数量,主单状态2，3，4。待回复，部分回复，已完成
//            Integer orderListTotal = queryOrderListTotal(getToday(), ORDER_STATUS,
//                    companyCode);
//            log.info("queryOrderListTotal method getToday() = " + JSONObject.toJSONString(getToday()) + " | ORDER_STATUS = " + JSONObject.toJSONString(ORDER_STATUS) + " | " +
//                    "companyCode =" + JSONObject.toJSONString(companyCode) + " | orderListTotal = " + JSONObject.toJSONString(orderListTotal));
//            //提报单量
//            DataInfo ordersSize = getQuantityFormatForForecastOrder(orderListTotal);
//            log.info("getQuantityFormatForForecastOrder method1 orderListTotal = "
//                    + JSONObject.toJSONString(orderListTotal) + " | ordersSize = " + JSONObject.toJSONString(ordersSize));
//            forecastOrderReportsResponse.setOrdersSize(ordersSize.getValue());
//            //提报单量小数点后位数
//            forecastOrderReportsResponse.setOrdersSizePoint(ordersSize.getTail());
//            //提报单量较前一天比值
//            String ordersCompare = getOrdersCompare(companyCode, ORDER_STATUS);
//            log.info("getOrdersCompare method companyCode = " + JSONObject.toJSONString(companyCode) +
//                    " | ORDER_STATUS = " + JSONObject.toJSONString(ORDER_STATUS) +
//                    " | ordersCompare = " + ordersCompare);
//            forecastOrderReportsResponse.setOrdersCompare((ordersCompare.contains("%")) ? ordersCompare : ordersCompare + "%");
//            //提报单量单位
//            forecastOrderReportsResponse.setOrdersSizeUnit(ordersSize.getUnit());
//            //提报单量较前日比值符号
//            String orderSizeSign = getSign(ordersCompare);
//            forecastOrderReportsResponse.setOrdersSizeSign(orderSizeSign);
//            //已回复单量
//            Integer repliedOrderSize = getRepliedOrderSize(companyCode, SUB_ORDER_STATUS);
//            log.info("getRepliedOrderSize method1 companyCode = " + JSONObject.toJSONString(companyCode) +
//                    " | ORDER_STATUS = " + JSONObject.toJSONString(SUB_ORDER_STATUS) +
//                    " | repliedOrderSize = " + JSONObject.toJSONString(repliedOrderSize));
//            DataInfo repliedOrderSizeDataInfo = getQuantityFormatForForecastOrder(repliedOrderSize);
//            log.info("getQuantityFormatForForecastOrder method2 repliedOrderSize = " + JSONObject.toJSONString(repliedOrderSize) +
//                    " | repliedOrderSizeDataInfo = " + JSONObject.toJSONString(repliedOrderSizeDataInfo));
//            forecastOrderReportsResponse.setRepliedOrderSize(repliedOrderSizeDataInfo.getValue());
//            //已回复单量小数点后
//            forecastOrderReportsResponse.setRepliedOrderSizePoint(repliedOrderSizeDataInfo.getTail());
//            //已回复单量较前一日比值
//            String repliedOrderSizeCompare = getRepliedOrderSizeCompare(companyCode, SUB_ORDER_STATUS);
//            log.info("getRepliedOrderSizeCompare method companyCode = " + JSONObject.toJSONString(companyCode) +
//                    " | SUB_ORDER_STATUS = " + JSONObject.toJSONString(SUB_ORDER_STATUS) +
//                    " | repliedOrderSizeCompare = " + JSONObject.toJSONString(repliedOrderSizeCompare));
//            forecastOrderReportsResponse.setRepliedOrderSizeCompare(repliedOrderSizeCompare);
//
//            //已回复单量单位
////        String repliedOrderSizeUnit = getUnit(repliedOrderSize);
//            forecastOrderReportsResponse.setRepliedOrderSizeUnit(repliedOrderSizeDataInfo.getUnit());
//            //比值符号
//            String repliedOrderSizeSign = getSign(repliedOrderSizeCompare);
//            forecastOrderReportsResponse.setRepliedOrderSizeSign(repliedOrderSizeSign);
//
//            //已回复单量/提报量 = 占比
//            String[] res = getProportionOfReplies((Objects.isNull(orderListTotal) ? 0 : orderListTotal), repliedOrderSize);
//            log.info("getProportionOfReplies method1 orderListTotal = " + JSONObject.toJSONString(orderListTotal) +
//                    " | repliedOrderSize = " + JSONObject.toJSONString(repliedOrderSize) +
//                    " | res = " + JSONObject.toJSONString(res));
//            if (Objects.nonNull(res) && res.length > 1) {
//                forecastOrderReportsResponse.setOrdersProportionOfReplies(res[0]);
//                forecastOrderReportsResponse.setOrderSizeTail("." + res[1]);
//            }
//
//            //处理提报数逻辑（子单中的货品件数）
//            //子单总件数(提报数量)
//            CountForecastQuantityForReport2Response orderLines = queryOrderLine(ORDER_STATUS, getToday(), companyCode, null);
//            log.info("queryOrderLine method1 ORDER_STATUS = " + JSONObject.toJSONString(ORDER_STATUS) +
//                    " | getToday = " + JSONObject.toJSONString(getToday()) +
//                    " | companyCode = " + JSONObject.toJSONString(companyCode) +
//                    "| orderLines = " + JSONObject.toJSONString(orderLines));
//
//            Integer quantity = orderLines.getQuantity();
//            DataInfo quantityDataInfo = getQuantityFormat(Objects.isNull(quantity) ? 0 : quantity);
//            forecastOrderReportsResponse.setOrderDetailsSize(quantityDataInfo.getValue());
//
//            //总件数小数点后位数
//            forecastOrderReportsResponse.setOrderDetailsSizePoint(quantityDataInfo.getTail());
//
//            //单位
////        String orderDetailsSizeUnit = getUnit(orderLines.getQuantity());
//            forecastOrderReportsResponse.setOrderDetailsSizeUnit(quantityDataInfo.getUnit());
//
//            //提报数量与前一日比值
//            String orderDetailsCompare = getRepliedOrderDetailsCompare(0, companyCode, ORDER_STATUS) + "%";
//            log.info("getRepliedOrderDetailsCompare method1 0  companyCode = " + JSONObject.toJSONString(companyCode) +
//                    " | ORDER_STATUS = " + JSONObject.toJSONString(ORDER_STATUS) +
//                    " | orderDetailsCompare = " + JSONObject.toJSONString(orderDetailsCompare));
//            forecastOrderReportsResponse.setOrderDetailsCompare(orderDetailsCompare);
//
//            //提报数量符号
//            String orderDetailsSizeSign = getSign(orderDetailsCompare);
//            forecastOrderReportsResponse.setOrderDetailsSizeSign(orderDetailsSizeSign);
//
//            //查询已回复数量
//            CountForecastQuantityForReport2Response repliedOrderDetailsSizeResponse = queryOrderLine(SUB_ORDER_STATUS, getToday(), companyCode, null);
//            log.info("queryOrderLine method2 SUB_ORDER_STATUS = " + JSONObject.toJSONString(SUB_ORDER_STATUS) +
//                    " | getToday() = " + JSONObject.toJSONString(getToday()) +
//                    " | companyCode = " + JSONObject.toJSONString(companyCode) +
//                    " | repliedOrderDetailsSizeResponse = " + JSONObject.toJSONString(repliedOrderDetailsSizeResponse));
//            //已回复数量
//            Integer repliedOrderDetailsSize = repliedOrderDetailsSizeResponse.getQuantity();
//
//            DataInfo repliedOrderDetailsSizeDataInfo = getQuantityFormat(Objects.isNull(repliedOrderDetailsSize) ? 0 : repliedOrderDetailsSize);
//
//            forecastOrderReportsResponse.setRepliedOrderDetailsSize(repliedOrderDetailsSizeDataInfo.getValue());
//            //已回复数量小数点后数值
//            forecastOrderReportsResponse.setRepliedOrderDetailsSizePoint(repliedOrderDetailsSizeDataInfo.getTail());
//
//            String repliedOrderDetailsCompare = getRepliedOrderDetailsCompare(0, companyCode, SUB_ORDER_STATUS) + "%";
//            log.info("getRepliedOrderDetailsCompare method2 1 companyCode = " + JSONObject.toJSONString(companyCode) +
//                    " | SUB_ORDER_STATUS = " + JSONObject.toJSONString(SUB_ORDER_STATUS) +
//                    " | repliedOrderDetailsCompare = " + JSONObject.toJSONString(repliedOrderDetailsCompare));
//            forecastOrderReportsResponse.setRepliedOrderDetailsCompare(repliedOrderDetailsCompare);
//
////        String repliedOrderDetailsSizeUnit = getUnit(repliedOrderDetailsSize);
//
//            forecastOrderReportsResponse.setRepliedOrderDetailsSizeUnit(repliedOrderDetailsSizeDataInfo.getUnit());
//
//            String repliedOrderDetailsSizeSign = getSign(repliedOrderDetailsCompare);
//
//            forecastOrderReportsResponse.setRepliedOrderDetailsSizeSign(repliedOrderDetailsSizeSign);
//
//            String[] res2 = getProportionOfReplies(quantity, repliedOrderDetailsSize);
//            log.info("getProportionOfReplies method2 repliedOrderDetailsSize = " + JSONObject.toJSONString(repliedOrderDetailsSize) +
//                    " | quantity = " + JSONObject.toJSONString(quantity) +
//                    " | res2 = " + JSONObject.toJSONString(res2));
//            if (Objects.nonNull(res2) && res.length > 1) {
//                forecastOrderReportsResponse.setOrderDetailsProportionOfReplies(new BigDecimal(res2[0]).toString());
//                forecastOrderReportsResponse.setOrderDetailTail("." + res2[1]);
//            }
//
//            //处理新增待回复数量
//            //待回复数量，提报量-已回复数量
//            Integer waitRepliedDetailsSize = (Objects.isNull(quantity) ? 0 : quantity) -
//                    (Objects.isNull(repliedOrderDetailsSize) ? 0 : repliedOrderDetailsSize);
//            //格式化
//            DataInfo waitSize = getQuantityFormat(Objects.isNull(waitRepliedDetailsSize) ? 0 : waitRepliedDetailsSize);
//            //待回复数量
//            forecastOrderReportsResponse.setWaitRepliedDetailsSize(waitSize.getValue());
//            //待回复数量小数点后数值
//            forecastOrderReportsResponse.setWaitRepliedDetailsPoint(waitSize.getTail());
//            //待回复数量单位
//            forecastOrderReportsResponse.setWaitRepliedDetailsSizeUnit(waitSize.getUnit());
//            //待回复较前一日比值
//            String waitRepliedDetailsCompare = getWaitRepliedDetailsCompare(companyCode, waitRepliedDetailsSize);
//            forecastOrderReportsResponse.setWaitRepliedDetailsCompare(waitRepliedDetailsCompare);
//            //待回复较前一日比值符号
//            String waitRepliedDetailsCompareSign = getSign(waitRepliedDetailsCompare);
//            forecastOrderReportsResponse.setWaitRepliedDetailsCompareSign(waitRepliedDetailsCompareSign);
//
//
//            //处理top5
//            List<ForecastOrderReportsTopNumResponse> topNumResponses = buildForecastOrderReportsTopNumList(companyCode, SUB_ORDER_STATUS);
//            forecastOrderReportsResponse.setForecastOrderReportsTopNumList(topNumResponses);
//            log.info("buildForecastOrderReportsTopNumList method companyCode = " + JSONObject.toJSONString(companyCode) +
//                    " | COMPLETED_STATUS = " + JSONObject.toJSONString(SUB_ORDER_STATUS) +
//                    " | topNumResponses = " + JSONObject.toJSONString(topNumResponses));
//            //获取当天所有已被拒绝的子单中的货品数量的总和
//            Long detailTotalSum = getForecastOrderLineAllRefuseReasonNum(companyCode, getToday());
//            log.info("getForecastOrderLineAllRefuseReasonNum method companyCode = " + JSONObject.toJSONString(companyCode) +
//                    " | getToday() = " + JSONObject.toJSONString(getToday()) +
//                    " | detailTotalSum = " + JSONObject.toJSONString(detailTotalSum));
//            List<ForecastOrderReportsTopListResponse> topListResponses = buildForecastOrderReportsTopList(detailTotalSum, companyCode, SUB_ORDER_STATUS);
//
//            forecastOrderReportsResponse.setForecastOrderReportsTopList(topListResponses);
//
//            log.info("buildForecastOrderReportsTopList method detailTotalSum = " + JSONObject.toJSONString(detailTotalSum) +
//                    " | companyCode = " + JSONObject.toJSONString(companyCode) +
//                    " | COMPLETED_STATUS = " + JSONObject.toJSONString(SUB_ORDER_STATUS) +
//                    " | topListResponses = " + JSONObject.toJSONString(topListResponses));
//            SimpleDateFormat dateFm = new SimpleDateFormat("yyyy/MM/dd"); //格式化当前系统日期
//            String dateTime = dateFm.format(new Date());
//            forecastOrderReportsResponse.setNowDate(dateTime);
//
//            //年后新需求改版
//            //渠道订单回复分析
//            List<ChannelOrderListResponse> channelOrderList = buildChannelOrderList(companyCode);
//            forecastOrderReportsResponse.setChannelOrderList(channelOrderList);
//
//            //部门回复分析
//            List<DepOrderListResponse> depOrderListResponses = buildDepOrderList(companyCode, channelOrderList);
//            forecastOrderReportsResponse.setDepOrderList(depOrderListResponses);
//
//            //日订单回复分析
//            DailyOrderListResponse depOrderList = buildDailyOrder(companyCode);
//            forecastOrderReportsResponse.setDailyOrderList(depOrderList);
//
//        } catch (Exception e) {
//            log.error("sys error msg", e);
//        }
        log.info("ForecastOrderReportsQueryServiceImpl.success response {}", JSONObject.toJSONString(forecastOrderReportsResponse));
        return Result.success(forecastOrderReportsResponse);
    }

    //根据销售组织 和 时间区间 前阶段区间 获取结果
    private Pair<OrderLineStatAmountResponse,OrderLineStatAmountResponse> getStatResponse(String salesOrgId,
                                                                                          List<Date> dates,
                                                                                          List<Date> previousDates){
        //2022.12.19 修改逻辑 已回复金额 从销售子单中获取
        //页面选择时间段获取的子单
        CompletableFuture<OrderLineStatAmountResponse> future = CompletableFuture.supplyAsync(()->{
            return statSaleOrderLine(salesOrgId,dates.get(0),dates.get(1));
        },threadPoolTaskExecutor);

        //前阶段的已回复数量
        CompletableFuture<OrderLineStatAmountResponse> previousFuture = CompletableFuture.supplyAsync(() ->{
            return statSaleOrderLine(salesOrgId,previousDates.get(0),previousDates.get(1));
        },threadPoolTaskExecutor);
        OrderLineStatAmountResponse statAmountResponse = null;
        OrderLineStatAmountResponse previousStatResponse = null;
        try {
            statAmountResponse = future.get();
            previousStatResponse = previousFuture.get();
            return Pair.of(statAmountResponse,previousStatResponse);
        } catch (Throwable e){
            log.error("queryOrderInfo_stat_error",e);
        }
        return null;
    }

    private static void checkDate(String begin, String end){
        if (org.apache.commons.lang3.StringUtils.isAnyBlank(begin,end)){
            throw new FacadeException("OTS-03-005-00-15-180");
        }
        Date beginDate = TimeUtil.parseYYYY_MM_dd(begin);
        Date endDate = TimeUtil.parseYYYY_MM_dd(end);
        if (beginDate == null){
            throw new FacadeException("OTS-03-005-00-15-182");
        }
        if (endDate == null){
            throw new FacadeException("OTS-03-005-00-15-183");
        }
        if (beginDate.after(endDate)){
            throw new FacadeException("OTS-03-005-00-15-184");
        }
        long time = endDate.getTime() - beginDate.getTime();
        if (time > 1000L * 60 * 60 * 24 * 90){
            throw new FacadeException("OTS-03-005-00-15-181");
        }
    }
}
